Finished admin page - buttons, permissions, create admin, user editing, delete correctly, styling

This commit is contained in:
Kenneth Jao 2016-11-03 02:05:43 -04:00
parent 4a9c117814
commit 3a9b505abe
11 changed files with 303 additions and 104 deletions

View File

@ -1,4 +1,41 @@
.adminUserIcon { .content-wrapper {
background-image: url("/Backgrounds/escheresque_ste.png");
}
.content-wrapper h4 {
color: #FEFEFE;
}
.col-lg-3 {
-webkit-filter: drop-shadow(2px 2px 2px #CCC);
filter: drop-shadow(2px 2px 2px #666);
}
.main-header .logo {
background-color: #222d32;
}
.main-sidebar {
box-shadow: -2px 1px 1px 5px #666;
}
.navbar {
background-color: #2F414A !important;
box-shadow: 7px -2px 1px 5px #666;
}
.content-header h1, #adminAddWrapper {
background-color: #FFF;
border: 5px solid #FFF;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
}
.breadcrumb {
margin-right: 1%;
}
.adminUserIcon, .simpleUserIcon {
width: 2.7vw; width: 2.7vw;
margin: 1%; margin: 1%;
@ -52,5 +89,47 @@
} }
.approveStatus .fa-toggle-on { .approveStatus .fa-toggle-on {
color: #288cd3; color: #288CD3;
} }
.addAdmin {
width: 35% !important;
}
.simpleUserIcon {
margin: 0.5% 0.3% 0.5% 0.2%;
display: inline-block;
vertical-align: top;
cursor: default;
}
.simpleUserInfo {
margin: 0.5% 0.3% 0.5% 0.2%;
background-color: #FFF;
display: inline-block;
vertical-align: top;
}
.simpleUserInfo p {
margin: 1%;
}
.simpleUserInfo p:first-child {
font-weight: 400;
}
.simpleUserInfo p:last-child {
font-weight: 200;
color: #D8D8D8;
}
.addAdmin {
margin: 0 0 1% 1%;
display: inline-block !important;
}
#addAdmin {
margin-left: 1%;
display: inline-block;
}

View File

@ -14,4 +14,38 @@
<div class="approveStatus"> <div class="approveStatus">
<i class="fa fa-toggle-{{status}}" aria-hidden="true"></i> <i class="fa fa-toggle-{{status}}" aria-hidden="true"></i>
</div> </div>
</template>
<template name="userEditor">
{{#if superAdmin}}
{{> quickForm id="editUser" collection="Meteor.users" doc=userInfo schema="userSchema" type="update"}}
{{else}}
<h4>You are not authorized to edit users.</h4>
{{/if}}
</template>
<template name="createAdmin">
{{#if superAdmin}}
<div id="adminAddWrapper">
<h3>Search</h3>
<div>
{{> inputAutocomplete settings=userComplete class="form-control addAdmin" type="text" placeholder="Example: 1234@abc.xyz" }}
<button id="addAdmin" class="btn btn-primary">Add</button>
</div>
</div>
{{else}}
{{> disableUser}}
{{/if}}
</template>
<template name="disableUser">
<h4>You are not authorized to edit this.</h4>
</template>
<template name="simpleUser">
<img class="simpleUserIcon" src="{{services.google.picture}}">
<div class="simpleUserInfo">
<p>{{profile.name}}</p>
<p>{{services.google.email}}</p>
</div>
</template> </template>

View File

@ -12,7 +12,7 @@ Template.adminUserDisplay.helpers({
email: user.services.google.email, email: user.services.google.email,
id: user._id, id: user._id,
icon: user.services.google.picture icon: user.services.google.picture
}) });
} }
return userInfo; return userInfo;
} }
@ -20,7 +20,6 @@ Template.adminUserDisplay.helpers({
Template.statusButton.helpers({ Template.statusButton.helpers({
status() { status() {
console.log(this.value);
return (this.value) ? "on" : "off"; return (this.value) ? "on" : "off";
} }
}); });
@ -51,16 +50,54 @@ Template.AdminLTE.events({
if(!event.target.className.includes("adminUserInfo") && if(!event.target.className.includes("adminUserInfo") &&
!event.target.className.includes("adminUserIcon") && !event.target.className.includes("adminUserIcon") &&
openUserDisplay !== null) { openUserDisplay !== null) {
openUserDisplay.fadeOut(200); if(!openUserDisplay[0].contains(event.target)) {
openUserDisplay = null; openUserDisplay.fadeOut(200, function() {
openUserDisplay = null;
});
}
} }
} }
}); });
Template.statusButton.events({ Template.statusButton.events({
'click .approveStatus' () { 'click .approveStatus' () {
console.log(this.doc._id);
Meteor.call("approveClass", this.doc._id); Meteor.call("approveClass", this.doc._id);
} }
}) });
Template.userEditor.helpers({
userInfo : function() {
return Session.get("admin_doc")
},
superAdmin: function() {
return Roles.userIsInRole(Meteor.userId(), ['superadmin']);
}
});
Template.createAdmin.helpers({
userComplete() {
return {
position: "bottom",
limit: 7,
rules: [{
token: '',
collection: Meteor.users,
field: 'services.google.email',
filter: {roles: {$not: {$elemMatch: {$eq: "admin"}}}},
template: Template.simpleUser
}]
};
},
superAdmin: function() {
return Roles.userIsInRole(Meteor.userId(), ['superadmin']);
}
});
Template.createAdmin.events({
'click #addAdmin' () {
var value = document.getElementsByClassName("form-control")[0].value;
var user = Meteor.users.findOne({'services.google.email': value});
if(user === undefined) return;
Meteor.call("addAdmin", user._id);
}
})

View File

@ -221,7 +221,7 @@
animation: expand .7s ease 1; animation: expand .7s ease 1;
} }
.-autocomplete-container { .noScroll .-autocomplete-container {
display: none; display: none;
} }

View File

@ -2,6 +2,7 @@ schools = new Mongo.Collection("Schools");
classes = new Mongo.Collection("Classes"); classes = new Mongo.Collection("Classes");
work = new Mongo.Collection("Work"); work = new Mongo.Collection("Work");
requests = new Mongo.Collection("Requests"); requests = new Mongo.Collection("Requests");
admins = Meteor.users;
schools.schema = new SimpleSchema({ schools.schema = new SimpleSchema({
name: {type: String}, name: {type: String},
@ -23,7 +24,6 @@ classes.schema = new SimpleSchema({
subscribers: {type: [String], optional: true} subscribers: {type: [String], optional: true}
}); });
work.schema = new SimpleSchema({ work.schema = new SimpleSchema({
name: {type: String}, name: {type: String},
class: {type: String}, class: {type: String},
@ -41,7 +41,19 @@ work.schema = new SimpleSchema({
requests.schema = new SimpleSchema({ requests.schema = new SimpleSchema({
requestor: {type: String}, requestor: {type: String},
request: {type: String}, request: {type: String},
timeRequested: {type: Date} timeRequested: {type: Date},
'info.users': {type: [Object], label: "Debug Users"},
'info.userInfo': {type: Object, label: "Debug User Info"},
'info.userClasses': {type: [Object], label: "Debug User Classes"}
});
userSchema = new SimpleSchema({
'profile.name': {type: String, label: "Name"},
'profile.grade': {type: Number, label: "Graduation Year"},
'profile.school': {type: String, label: "School"},
'services.google.email': {type: String, label: "Email"},
'services.google.picture': {type: String, label: "Icon URL"},
'profile.classes': {type: [String], label: "Classes"}
}); });
schools.attachSchema(schools.schema); schools.attachSchema(schools.schema);

View File

@ -0,0 +1,110 @@
AdminConfig = {
name: 'Hourglass',
collections: {
schools: {
icon: 'university',
tableColumns: [
{ label: 'ID', name: '_id' },
{ label: 'Name', name: 'name' }
],
color: 'red',
label: 'Schools'
},
classes: {
icon: 'graduation-cap',
tableColumns: [
{ label: 'ID', name: '_id' },
{ label: 'School', name: 'school' },
{ label: 'Name', name: 'name' },
{ label: 'Hour', name: 'hour' },
{ label: 'Teacher', name: 'teacher' },
{ label: 'Admin', name: 'admin', template: 'adminUserDisplay' },
{ label: 'Status', name: 'status', template: 'statusButton'},
{ label: 'Code', name: 'code' },
{ label: 'Privacy', name: 'privacy' },
{ label: 'Category', name: 'category' },
{ label: 'Moderators', name: 'moderators', template: 'adminUserDisplay' },
{ label: 'Banned', name: 'banned', template: 'adminUserDisplay' },
{ label: 'Subscribers', name: 'subscribers', template: 'adminUserDisplay'}
],
color: 'blue',
label: 'Classes'
},
work: {
icon: 'pencil',
tableColumns: [
{ label: 'ID', name: '_id' },
{ label: 'Class', name: 'class' },
{ label: 'Name', name: 'name' },
{ label: 'Due Date', name: 'dueDate' },
{ label: 'Description', name: 'description' },
{ label: 'Creator', name: 'creator', template: 'adminUserDisplay' },
{ label: 'Comments', name: 'comments' },
{ label: 'Confirmations', name: 'confirmations', template: 'adminUserDisplay' },
{ label: 'Reports', name: 'reports', template: 'adminUserDisplay' },
{ label: 'Done', name: 'done', template: 'adminUserDisplay' },
{ label: 'Type', name: 'type' }
],
color: 'yellow',
label: 'Work'
},
requests: {
icon: 'exclamation-triangle',
tableColumns: [
{ label: 'ID', name: '_id' },
{ label: 'User', name: 'requestor', template: 'adminUserDisplay' },
{ label: 'Request', name: 'request' },
{ label: 'Time', name: 'timeRequested' }
],
color: 'green',
label: 'Requests'
},
'Meteor.users': {
icon: 'user',
tableColumns: [
{ label: 'ID', name: '_id' },
{ label: 'Email', name: 'services.google.email' },
{ label: 'Name', name: 'profile.name' },
{ label: 'School', name: 'profile.school' },
{ label: 'Graduation Year', name:'profile.grade' },
{ label: 'Icon', name: '_id', template: 'adminUserDisplay' },
],
templates: {
new: {
name: 'disableUser'
},
edit: {
name: 'userEditor'
}
},
color: 'light-blue',
label: 'Users'
},
admins: {
icon: 'user-plus',
tableColumns: [
{ label: 'ID', name: '_id' },
{ label: 'Email', name: 'services.google.email' },
{ label: 'Name', name: 'profile.name' },
{ label: 'School', name: 'profile.school' },
{ label: 'Graduation Year', name:'profile.grade' },
{ label: 'Icon', name: '_id', template: 'adminUserDisplay' },
],
templates: {
new: {
name: 'createAdmin'
},
edit: {
name: 'disableUser'
}
},
selector: function() {
return {roles: {$elemMatch: {$eq: "admin"}}}
},
showEditColumn: false,
color: 'purple',
label: 'Admins'
},
}
};

View File

@ -121,79 +121,4 @@ options = {
] ]
} }
AdminConfig = {
name: 'Hourglass',
collections: {
schools: {
icon: 'university',
tableColumns: [
{ label: 'ID', name: '_id' },
{ label: 'Name', name: 'name' }
],
color: 'red',
label: 'Schools'
},
classes: {
icon: 'graduation-cap',
tableColumns: [
{ label: 'ID', name: '_id' },
{ label: 'School', name: 'school' },
{ label: 'Name', name: 'name' },
{ label: 'Hour', name: 'hour' },
{ label: 'Teacher', name: 'teacher' },
{ label: 'Admin', name: 'admin', template: 'adminUserDisplay' },
{ label: 'Status', name: 'status', template: 'statusButton'},
{ label: 'Code', name: 'code' },
{ label: 'Privacy', name: 'privacy' },
{ label: 'Category', name: 'category' },
{ label: 'Moderators', name: 'moderators', template: 'adminUserDisplay' },
{ label: 'Banned', name: 'banned', template: 'adminUserDisplay' },
{ label: 'Subscribers', name: 'subscribers', template: 'adminUserDisplay'}
],
color: 'blue',
label: 'Classes'
},
work: {
icon: 'pencil',
tableColumns: [
{ label: 'ID', name: '_id' },
{ label: 'Class', name: 'class' },
{ label: 'Name', name: 'name' },
{ label: 'Due Date', name: 'dueDate' },
{ label: 'Description', name: 'description' },
{ label: 'Creator', name: 'creator', template: 'adminUserDisplay' },
{ label: 'Comments', name: 'comments' },
{ label: 'Confirmations', name: 'confirmations', template: 'adminUserDisplay' },
{ label: 'Reports', name: 'reports', template: 'adminUserDisplay' },
{ label: 'Done', name: 'done', template: 'adminUserDisplay' },
{ label: 'Type', name: 'type' }
],
color: 'yellow',
label: 'Work'
},
requests: {
icon: 'exclamation-triangle',
tableColumns: [
{ label: 'ID', name: '_id' },
{ label: 'User', name: 'requestor', template: 'adminUserDisplay' },
{ label: 'Request', name: 'request' },
{ label: 'Time', name: 'timeRequested' }
],
color: 'green',
label: 'Requests'
},
'Meteor.users': {
icon: 'user',
tableColumns: [
{ label: 'ID', name: '_id' },
{ label: 'Email', name: 'services.google.email' },
{ label: 'Name', name: 'profile.name' },
{ label: 'Icon', name: '_id', template: 'adminUserDisplay' }
],
color: 'purple',
label: 'Users'
}
}
};
serverData = null; serverData = null;

View File

@ -80,19 +80,6 @@ Router.route('/user/:email', {
} }
}); });
/*Router.route('/admin', {
data: function() {
return true;
},
action: function() {
if (!Roles.userIsInRole(Meteor.userId(), ['admin', 'superadmin'])) {
this.redirect("/");
} else {
this.render("admin");
}
}
});*/
Router.configure({ Router.configure({
notFoundTemplate: "NotFound" notFoundTemplate: "NotFound"
}); });

View File

@ -12,8 +12,15 @@ Template.AdminDeleteModal.events
'click #confirm-delete': () -> 'click #confirm-delete': () ->
collection = Session.get 'admin_collection_name' collection = Session.get 'admin_collection_name'
_id = Session.get 'admin_id' _id = Session.get 'admin_id'
Meteor.call 'adminRemoveDoc', collection, _id, (e,r)-> if collection == 'classes'
$('#admin-delete-modal').modal('hide') Meteor.call 'deleteClass', _id, (e,r) ->
$('#admin-delete-modal').modal('hide')
else if collection == 'admins'
Meteor.call 'deleteAdmin', _id, (e,r) ->
$('#admin-delete-modal').modal('hide')
else
Meteor.call 'adminRemoveDoc', collection, _id, (e,r)->
$('#admin-delete-modal').modal('hide')
Template.AdminDashboardUsersEdit.events Template.AdminDashboardUsersEdit.events
'click .btn-add-role': (e,t) -> 'click .btn-add-role': (e,t) ->

View File

@ -88,6 +88,8 @@ UI.registerHelper 'adminCollectionLabel', (collection)->
UI.registerHelper 'adminCollectionCount', (collection)-> UI.registerHelper 'adminCollectionCount', (collection)->
if collection == 'Users' if collection == 'Users'
Meteor.users.find().count() Meteor.users.find().count()
else if collection == 'admins'
Meteor.users.find({roles: {$elemMatch: {$eq: "admin"}}}).count()
else else
AdminCollectionsCount.findOne({collection: collection})?.count AdminCollectionsCount.findOne({collection: collection})?.count

View File

@ -15,6 +15,12 @@ var superadmins = [
var worktype = ["test", "quiz", "project", "normal", "other"]; var worktype = ["test", "quiz", "project", "normal", "other"];
Meteor.users.allow({
update: function(userId, doc, fields, modifier) {
return Roles.userIsInRole(userId, ['superadmin']);
}
});
Meteor.publish('schools', function() { Meteor.publish('schools', function() {
return schools.find(); return schools.find();
}); });
@ -234,7 +240,7 @@ function securityCheck(checklist, input) {
break; break;
// Request too long // Request too long
case 19: case 19:
if (typeof input.request !== "string" || input.request.length > 500) error = 16; if (typeof input.content !== "string" || input.content.length > 500) error = 16;
break; break;
// Is valid work type // Is valid work type
case 20: case 20:
@ -258,7 +264,7 @@ function securityCheck(checklist, input) {
break; break;
// User is logged in // User is logged in
case 25: case 25:
if (Meteor.userId === null) error = errors.length - 1; if (Meteor.userId() === null) error = errors.length - 1;
break; break;
} }
results.push(error); results.push(error);