Added settings and messages to manage sending web inquiries to one or more email addresses specified via the web management interface.
This commit is contained in:
@@ -6,16 +6,16 @@
|
|||||||
|
|
||||||
meteor-base@1.4.0 # Packages every Meteor app needs to have
|
meteor-base@1.4.0 # Packages every Meteor app needs to have
|
||||||
mobile-experience@1.0.5 # Packages for a great mobile UX
|
mobile-experience@1.0.5 # Packages for a great mobile UX
|
||||||
mongo@1.6.0 # The database Meteor supports right now
|
mongo@1.6.2 # The database Meteor supports right now
|
||||||
blaze-html-templates@1.0.4 # Compile .html files into Meteor Blaze views
|
blaze-html-templates@1.0.4 # Compile .html files into Meteor Blaze views
|
||||||
reactive-var@1.0.11 # Reactive variable for tracker
|
reactive-var@1.0.11 # Reactive variable for tracker
|
||||||
reactive-dict@1.2.1 # ???
|
reactive-dict@1.3.0 # ???
|
||||||
tracker@1.2.0 # Meteor's client-side reactive programming library
|
tracker@1.2.0 # Meteor's client-side reactive programming library
|
||||||
tomwasd:history-polyfill # Adds IE 8/9 support for HTML5 history.
|
tomwasd:history-polyfill # Adds IE 8/9 support for HTML5 history.
|
||||||
email@1.2.3 # Adds the Meteor/Email package for sending lost password emails
|
email@1.2.3 # Adds the Meteor/Email package for sending lost password emails
|
||||||
|
|
||||||
standard-minifier-css@1.5.2 # CSS minifier run for production mode
|
standard-minifier-css@1.5.3 # CSS minifier run for production mode
|
||||||
standard-minifier-js@2.4.0 # JS minifier run for production mode
|
standard-minifier-js@2.4.1 # JS minifier run for production mode
|
||||||
es5-shim@4.8.0 # ECMAScript 5 compatibility for older browsers.
|
es5-shim@4.8.0 # ECMAScript 5 compatibility for older browsers.
|
||||||
poorvavyas:es6-shim
|
poorvavyas:es6-shim
|
||||||
ecmascript@0.12.4 # Enable ECMAScript2015+ syntax in app code
|
ecmascript@0.12.4 # Enable ECMAScript2015+ syntax in app code
|
||||||
@@ -60,7 +60,7 @@ juliancwirko:s-alert # Client error/alert handling
|
|||||||
jcbernack:reactive-aggregate # Allows us to create a new client collection (from the server) with the contents being an aggregate of server data. Note that aggregation can only be done on the server currently as mini-mongo does not support it.
|
jcbernack:reactive-aggregate # Allows us to create a new client collection (from the server) with the contents being an aggregate of server data. Note that aggregation can only be done on the server currently as mini-mongo does not support it.
|
||||||
ostrio:logger
|
ostrio:logger
|
||||||
ostrio:loggermongo
|
ostrio:loggermongo
|
||||||
dynamic-import@0.5.0
|
dynamic-import@0.5.1
|
||||||
markdown@1.0.12
|
markdown@1.0.12
|
||||||
wcrisman:jquery-custom-scrollbar
|
wcrisman:jquery-custom-scrollbar
|
||||||
wcrisman:server-side-seo # A custom plugin to take all HTML from the app, and place the templates in a map in a file in the private folder for use at runtime to generate search engine readable html. See code in the /packages folder for this project.
|
wcrisman:server-side-seo # A custom plugin to take all HTML from the app, and place the templates in a map in a file in the private folder for use at runtime to generate search engine readable html. See code in the /packages folder for this project.
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
METEOR@1.8.0.2
|
METEOR@1.8.1
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ aldeed:schema-index@3.0.0
|
|||||||
aldeed:template-extension@4.1.0
|
aldeed:template-extension@4.1.0
|
||||||
allow-deny@1.1.0
|
allow-deny@1.1.0
|
||||||
arillo:flow-router-helpers@0.5.2
|
arillo:flow-router-helpers@0.5.2
|
||||||
autoupdate@1.5.0
|
autoupdate@1.6.0
|
||||||
babel-compiler@7.2.4
|
babel-compiler@7.3.4
|
||||||
babel-runtime@1.3.0
|
babel-runtime@1.3.0
|
||||||
base64@1.0.11
|
base64@1.0.11
|
||||||
binary-heap@1.0.11
|
binary-heap@1.0.11
|
||||||
@@ -24,7 +24,7 @@ ddp@1.4.0
|
|||||||
ddp-client@2.3.3
|
ddp-client@2.3.3
|
||||||
ddp-common@1.4.0
|
ddp-common@1.4.0
|
||||||
ddp-rate-limiter@1.0.7
|
ddp-rate-limiter@1.0.7
|
||||||
ddp-server@2.2.0
|
ddp-server@2.3.0
|
||||||
deps@1.0.12
|
deps@1.0.12
|
||||||
diff-sequence@1.1.1
|
diff-sequence@1.1.1
|
||||||
dynamic-import@0.5.1
|
dynamic-import@0.5.1
|
||||||
@@ -35,7 +35,7 @@ ecmascript-runtime-server@0.7.1
|
|||||||
ejson@1.1.0
|
ejson@1.1.0
|
||||||
email@1.2.3
|
email@1.2.3
|
||||||
es5-shim@4.8.0
|
es5-shim@4.8.0
|
||||||
fetch@0.1.0
|
fetch@0.1.1
|
||||||
fortawesome:fontawesome@4.7.0
|
fortawesome:fontawesome@4.7.0
|
||||||
geojson-utils@1.0.10
|
geojson-utils@1.0.10
|
||||||
hot-code-push@1.0.4
|
hot-code-push@1.0.4
|
||||||
@@ -55,7 +55,7 @@ localstorage@1.2.0
|
|||||||
logging@1.1.20
|
logging@1.1.20
|
||||||
manuel:reactivearray@1.0.9
|
manuel:reactivearray@1.0.9
|
||||||
markdown@1.0.12
|
markdown@1.0.12
|
||||||
meteor@1.9.2
|
meteor@1.9.3
|
||||||
meteor-base@1.4.0
|
meteor-base@1.4.0
|
||||||
meteorhacks:picker@1.0.3
|
meteorhacks:picker@1.0.3
|
||||||
meteorhacks:ssr@2.2.0
|
meteorhacks:ssr@2.2.0
|
||||||
@@ -76,24 +76,24 @@ meteortoys:sub@4.0.0
|
|||||||
meteortoys:throttle@4.0.0
|
meteortoys:throttle@4.0.0
|
||||||
meteortoys:toggle@4.0.0
|
meteortoys:toggle@4.0.0
|
||||||
meteortoys:toykit@4.0.2
|
meteortoys:toykit@4.0.2
|
||||||
minifier-css@1.4.1
|
minifier-css@1.4.2
|
||||||
minifier-js@2.4.0
|
minifier-js@2.4.1
|
||||||
minimongo@1.4.5
|
minimongo@1.4.5
|
||||||
mizzao:bootboxjs@4.4.0
|
mizzao:bootboxjs@4.4.0
|
||||||
mobile-experience@1.0.5
|
mobile-experience@1.0.5
|
||||||
mobile-status-bar@1.0.14
|
mobile-status-bar@1.0.14
|
||||||
modern-browsers@0.1.3
|
modern-browsers@0.1.4
|
||||||
modules@0.13.0
|
modules@0.13.0
|
||||||
modules-runtime@0.10.3
|
modules-runtime@0.10.3
|
||||||
momentjs:moment@2.23.0
|
momentjs:moment@2.23.0
|
||||||
mongo@1.6.0
|
mongo@1.6.2
|
||||||
mongo-decimal@0.1.0
|
mongo-decimal@0.1.1
|
||||||
mongo-dev-server@1.1.0
|
mongo-dev-server@1.1.0
|
||||||
mongo-id@1.0.7
|
mongo-id@1.0.7
|
||||||
msavin:jetsetter@4.0.0
|
msavin:jetsetter@4.0.0
|
||||||
msavin:mongol@7.0.1
|
msavin:mongol@7.0.1
|
||||||
npm-bcrypt@0.9.3
|
npm-bcrypt@0.9.3
|
||||||
npm-mongo@3.1.1
|
npm-mongo@3.1.2
|
||||||
observe-sequence@1.0.16
|
observe-sequence@1.0.16
|
||||||
ordered-dict@1.1.0
|
ordered-dict@1.1.0
|
||||||
ostrio:cookies@2.3.0
|
ostrio:cookies@2.3.0
|
||||||
@@ -106,9 +106,9 @@ promise@0.11.2
|
|||||||
raix:eventemitter@0.1.3
|
raix:eventemitter@0.1.3
|
||||||
random@1.1.0
|
random@1.1.0
|
||||||
rate-limit@1.0.9
|
rate-limit@1.0.9
|
||||||
reactive-dict@1.2.1
|
reactive-dict@1.3.0
|
||||||
reactive-var@1.0.11
|
reactive-var@1.0.11
|
||||||
reload@1.2.0
|
reload@1.3.0
|
||||||
retry@1.1.0
|
retry@1.1.0
|
||||||
routepolicy@1.1.0
|
routepolicy@1.1.0
|
||||||
service-configuration@1.0.11
|
service-configuration@1.0.11
|
||||||
@@ -120,8 +120,8 @@ softwarerero:accounts-t9n@1.3.11
|
|||||||
spacebars@1.0.15
|
spacebars@1.0.15
|
||||||
spacebars-compiler@1.1.3
|
spacebars-compiler@1.1.3
|
||||||
srp@1.0.12
|
srp@1.0.12
|
||||||
standard-minifier-css@1.5.2
|
standard-minifier-css@1.5.3
|
||||||
standard-minifier-js@2.4.0
|
standard-minifier-js@2.4.1
|
||||||
stylus@2.513.14
|
stylus@2.513.14
|
||||||
templating@1.3.2
|
templating@1.3.2
|
||||||
templating-compiler@1.3.3
|
templating-compiler@1.3.3
|
||||||
@@ -138,6 +138,6 @@ useraccounts:flow-routing@1.14.2
|
|||||||
useraccounts:unstyled@1.14.2
|
useraccounts:unstyled@1.14.2
|
||||||
wcrisman:jquery-custom-scrollbar@3.0.0
|
wcrisman:jquery-custom-scrollbar@3.0.0
|
||||||
wcrisman:server-side-seo@1.0.0
|
wcrisman:server-side-seo@1.0.0
|
||||||
webapp@1.7.2
|
webapp@1.7.3
|
||||||
webapp-hashing@1.0.9
|
webapp-hashing@1.0.9
|
||||||
zimme:active-route@2.3.2
|
zimme:active-route@2.3.2
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ h3
|
|||||||
z-index: 999
|
z-index: 999
|
||||||
|
|
||||||
|
|
||||||
|
@import "../imports/ui/styles/snapTable.import.styl"
|
||||||
@import "../imports/ui/styles/effects.import.styl"
|
@import "../imports/ui/styles/effects.import.styl"
|
||||||
@import "../imports/ui/styles/buttons.import.styl"
|
@import "../imports/ui/styles/buttons.import.styl"
|
||||||
@import "../imports/ui/styles/maxHeightLayout.import.styl"
|
@import "../imports/ui/styles/maxHeightLayout.import.styl"
|
||||||
@@ -192,6 +192,7 @@ h3
|
|||||||
|
|
||||||
@import "../imports/ui/Home.import.styl"
|
@import "../imports/ui/Home.import.styl"
|
||||||
|
|
||||||
|
@import "../imports/ui/Admin/Messages.import.styl"
|
||||||
@import "../imports/ui/Admin/UserManagement.import.styl"
|
@import "../imports/ui/Admin/UserManagement.import.styl"
|
||||||
@import "../imports/ui/Admin/InternshipEditor.import.styl"
|
@import "../imports/ui/Admin/InternshipEditor.import.styl"
|
||||||
@import "../imports/ui/Admin/PageEditor.import.styl"
|
@import "../imports/ui/Admin/PageEditor.import.styl"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Meteor } from 'meteor/meteor';
|
import { Meteor } from 'meteor/meteor';
|
||||||
import { Mongo } from 'meteor/mongo';
|
import { Mongo } from 'meteor/mongo';
|
||||||
import { check } from 'meteor/check';
|
import { check } from 'meteor/check';
|
||||||
|
import { Email } from 'meteor/email';
|
||||||
import SimpleSchema from 'simpl-schema';
|
import SimpleSchema from 'simpl-schema';
|
||||||
|
|
||||||
let ContactUsMessages = new Mongo.Collection('ContactUsMessages');
|
let ContactUsMessages = new Mongo.Collection('ContactUsMessages');
|
||||||
@@ -32,7 +33,10 @@ ContactUsMessages.attachSchema(new SimpleSchema({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
if(Meteor.isServer) Meteor.publish('contactUsMessages', function() {
|
if(Meteor.isServer) Meteor.publish('contactUsMessages', function() {
|
||||||
return ContactUsMessages.find({});
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
return ContactUsMessages.find({});
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
});
|
});
|
||||||
|
|
||||||
if(Meteor.isServer) {
|
if(Meteor.isServer) {
|
||||||
@@ -42,10 +46,18 @@ if(Meteor.isServer) {
|
|||||||
check(email, String);
|
check(email, String);
|
||||||
check(message, String);
|
check(message, String);
|
||||||
|
|
||||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
ContactUsMessages.insert({name, email, message, createdAt: new Date()});
|
||||||
ContactUsMessages.insert({name, email, message, createdAt: new Date()});
|
|
||||||
|
try {
|
||||||
|
let settings = Meteor.collections.Settings.findOne();
|
||||||
|
|
||||||
|
if(settings && settings.forwardEmailsTo && settings.forwardEmailsTo.length > 0) {
|
||||||
|
Email.send({to: settings.forwardEmailsTo, from: "Do Not Reply <no-reply@andersonvalleyeducation.org>", subject: "Contact Us Message", text: "Email: " + email + "\n\n" + message});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
console.log(err);
|
||||||
}
|
}
|
||||||
else throw new Meteor.Error(403, "Not authorized.");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
52
imports/api/Settings.js
Normal file
52
imports/api/Settings.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import { Mongo } from 'meteor/mongo';
|
||||||
|
import { check } from 'meteor/check';
|
||||||
|
import SimpleSchema from 'simpl-schema';
|
||||||
|
|
||||||
|
let Settings = new Mongo.Collection('Settings');
|
||||||
|
let singletonId;
|
||||||
|
|
||||||
|
Settings.attachSchema(new SimpleSchema({
|
||||||
|
forwardEmailsTo: {
|
||||||
|
type: Array,
|
||||||
|
label: "Forward Emails To",
|
||||||
|
optional: true,
|
||||||
|
defaultValue: []
|
||||||
|
},
|
||||||
|
'forwardEmailsTo.$': {
|
||||||
|
type: String,
|
||||||
|
label: "Email",
|
||||||
|
regEx: SimpleSchema.RegEx.Email
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
if(Meteor.isServer) Meteor.publish('Settings', function() {
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
return Settings.find({});
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
});
|
||||||
|
|
||||||
|
if(Meteor.isServer) {
|
||||||
|
let singleton = Settings.findOne({});
|
||||||
|
|
||||||
|
if(!singleton) {
|
||||||
|
singletonId = Settings.insert({});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
singletonId = singleton._id;
|
||||||
|
}
|
||||||
|
|
||||||
|
Meteor.methods({
|
||||||
|
changeForwardEmailsTo: function(emails) {
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
check(emails, [String]);
|
||||||
|
|
||||||
|
Settings.update({_id: singletonId}, {$set: {forwardEmailsTo: emails}});
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Settings;
|
||||||
@@ -6,9 +6,10 @@ import ImageUploads from "./Images.js";
|
|||||||
import Slideshow from "./Slideshow.js";
|
import Slideshow from "./Slideshow.js";
|
||||||
import Internship from "./Internship.js";
|
import Internship from "./Internship.js";
|
||||||
import ContactUsMessages from "./ContactUsMessages.js";
|
import ContactUsMessages from "./ContactUsMessages.js";
|
||||||
|
import Settings from "./Settings.js";
|
||||||
|
|
||||||
//Save the collections in the Meteor.collections property for easy access without name conflicts.
|
//Save the collections in the Meteor.collections property for easy access without name conflicts.
|
||||||
Meteor.collections = {Users, UserRoles, Pages, Slideshow, Internship, ContactUsMessages, ImageUploads};
|
Meteor.collections = {Users, UserRoles, Pages, Slideshow, Internship, ContactUsMessages, ImageUploads, Settings};
|
||||||
|
|
||||||
//If this is the server then setup the default admin user if none exist.
|
//If this is the server then setup the default admin user if none exist.
|
||||||
if(Meteor.isServer) {
|
if(Meteor.isServer) {
|
||||||
|
|||||||
@@ -88,6 +88,13 @@ pri.route("/Admin/SlideshowPageEditor", {
|
|||||||
BlazeLayout.render("Admin", {content: "PageEditor"});
|
BlazeLayout.render("Admin", {content: "PageEditor"});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
pri.route("/Admin/Messages", {
|
||||||
|
name: "Messages",
|
||||||
|
action: function(params, queryParams) {
|
||||||
|
require("/imports/ui/Admin/Messages.js");
|
||||||
|
BlazeLayout.render("Admin", {content: "Messages"});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
//*** PUBLIC
|
//*** PUBLIC
|
||||||
pub.route('/', {
|
pub.route('/', {
|
||||||
|
|||||||
58
imports/ui/Admin/Messages.html
Normal file
58
imports/ui/Admin/Messages.html
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<template name="Messages">
|
||||||
|
<div id="messages" class="snapTable">
|
||||||
|
{{#if Template.subscriptionsReady}}
|
||||||
|
<div class="emailContainer"><label>Forward Messages To:</label>
|
||||||
|
<select class="emailEditor" multiple="multiple">
|
||||||
|
{{#each emails}}
|
||||||
|
<option value="{{this}}" selected>{{this}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="tableControls">
|
||||||
|
<div class="contentControls">
|
||||||
|
<a class="loadMoreLink {{#if disableLoadMore}}disabled{{/if}}" href="javascript:">Load More...</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="separatedTableHeader">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="email">Email</th>
|
||||||
|
<th class="message">Message</th>
|
||||||
|
<th class="date">Date</th>
|
||||||
|
<th class="actions">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="listContianer">
|
||||||
|
<div class="listRow">
|
||||||
|
<div class="listCell">
|
||||||
|
<div class="tableContainer mCustomScrollbar" data-mcs-theme="dark">
|
||||||
|
<table class="dataTable table table-striped table-hover">
|
||||||
|
<tbody>
|
||||||
|
{{#each messages}}
|
||||||
|
{{> Message}}
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="Message">
|
||||||
|
<tr class="messageDetails" data-id="{{_id}}">
|
||||||
|
<td class="email tdLarge noselect nonclickable">{{email}}</td>
|
||||||
|
<td class="message tdLarge noselect nonclickable">{{message}}</td>
|
||||||
|
<td class="date tdLarge noselect nonclickable">{{date}}</td>
|
||||||
|
<td class="actions center tdLarge"><i class="toggleHandled {{handledClass}} fa fa-mail fa-lg noselect clickable" aria-hidden="true"></i></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="fullMessage">
|
||||||
|
<td colspan="4"><div>{{{fullMessage}}}</div></td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
36
imports/ui/Admin/Messages.import.styl
vendored
Normal file
36
imports/ui/Admin/Messages.import.styl
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#messages
|
||||||
|
.emailContainer
|
||||||
|
width 100
|
||||||
|
position relative
|
||||||
|
.emailEditor
|
||||||
|
min-width 200px
|
||||||
|
width 100%
|
||||||
|
tr
|
||||||
|
> .email
|
||||||
|
width 300px
|
||||||
|
min-width 100px
|
||||||
|
> .message
|
||||||
|
width 50%
|
||||||
|
min-width 100px
|
||||||
|
max-width 200px
|
||||||
|
overflow hidden
|
||||||
|
text-overflow ellipsis
|
||||||
|
white-space nowrap
|
||||||
|
> .date
|
||||||
|
width 260px
|
||||||
|
min-width 260px
|
||||||
|
> .actions
|
||||||
|
width 80px
|
||||||
|
min-width 80px
|
||||||
|
.toggleHandled
|
||||||
|
color red
|
||||||
|
.toggleHandled.handled
|
||||||
|
color green
|
||||||
|
tr.fullMessage
|
||||||
|
display none
|
||||||
|
background-color #b8c1dc
|
||||||
|
font-weight 800
|
||||||
|
div
|
||||||
|
padding-left 20px
|
||||||
|
tr.fullMessage.display
|
||||||
|
display table-row
|
||||||
95
imports/ui/Admin/Messages.js
Normal file
95
imports/ui/Admin/Messages.js
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
import './Messages.html';
|
||||||
|
import swal from "sweetalert2";
|
||||||
|
|
||||||
|
const PREFIX = "Messages_";
|
||||||
|
|
||||||
|
Tracker.autorun(function() {
|
||||||
|
Meteor.subscribe("contactUsMessages");
|
||||||
|
Meteor.subscribe("Settings");
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.Messages.onCreated(function() {
|
||||||
|
Session.set(PREFIX + 'selected', null);
|
||||||
|
});
|
||||||
|
Template.Messages.onRendered(function() {
|
||||||
|
$(".tableContainer").mCustomScrollbar({
|
||||||
|
scrollButtons: {enable:true},
|
||||||
|
theme: "light-thick",
|
||||||
|
scrollbarPosition: "outside",
|
||||||
|
scrollEasing: "linear"
|
||||||
|
});
|
||||||
|
this.$(".emailEditor").select2({tags: true, tokenSeparators: [';']});
|
||||||
|
});
|
||||||
|
Template.Messages.helpers({
|
||||||
|
messages: function() {
|
||||||
|
return Meteor.collections.ContactUsMessages.find({}, {sort: {createdAt: 1}});
|
||||||
|
},
|
||||||
|
selected: function() {
|
||||||
|
return Session.get(PREFIX + "selected");
|
||||||
|
},
|
||||||
|
emails: function() {
|
||||||
|
let emails = [];
|
||||||
|
let settings = Meteor.collections.Settings.findOne({});
|
||||||
|
|
||||||
|
//Settings might be undefined if we are still loading.
|
||||||
|
if(settings) {
|
||||||
|
emails = settings.forwardEmailsTo;
|
||||||
|
|
||||||
|
//if(emails) {
|
||||||
|
// emails = emails.split(";");
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
return emails;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Template.Messages.events({
|
||||||
|
'change .emailEditor': function(e, t) {
|
||||||
|
let emails = t.$(".emailEditor").select2('data');
|
||||||
|
|
||||||
|
emails = emails.map((n)=>n.id);
|
||||||
|
console.log(emails);
|
||||||
|
Meteor.call("changeForwardEmailsTo", emails, function(err, result) {
|
||||||
|
if(err) console.log(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'click table.dataTable tr.messageDetails': function(event, template) {
|
||||||
|
let $tr = template.$(event.currentTarget);
|
||||||
|
|
||||||
|
if(Session.get(PREFIX + "selected") && $tr.data('id') === Session.get(PREFIX + "selected")._id) {
|
||||||
|
$tr.removeClass('selected');
|
||||||
|
$tr.next().removeClass('display');
|
||||||
|
Session.set(PREFIX + "selected", undefined);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$tr.siblings(".messageDetails").removeClass('selected');
|
||||||
|
$tr.siblings(".fullMessage").removeClass('display');
|
||||||
|
$tr.addClass('selected');
|
||||||
|
$tr.next().addClass('display');
|
||||||
|
Session.set(PREFIX + "selected", Meteor.collections.ContactUsMessages.findOne($tr.data('id')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Template.Message.onCreated(function() {
|
||||||
|
});
|
||||||
|
Template.Message.helpers({
|
||||||
|
date: function() {
|
||||||
|
return moment(this.createdAt).format("MM/DD/YYYY");
|
||||||
|
},
|
||||||
|
selected: function() {
|
||||||
|
return Session.get(PREFIX + "selected");
|
||||||
|
},
|
||||||
|
handledClass: function() {
|
||||||
|
return "";
|
||||||
|
},
|
||||||
|
fullMessage: function() {
|
||||||
|
return this.message.replace(/[\n\r]/g, "<br/>");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Template.Message.events({
|
||||||
|
"click .toggleHandled": function(event, template) {
|
||||||
|
//TODO: Mark the message as handled.
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -45,6 +45,11 @@
|
|||||||
News & Notices
|
News & Notices
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="{{isActiveRoute 'Messages'}}">
|
||||||
|
<a href="{{pathFor 'Messages'}}">
|
||||||
|
Messages
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li class="{{isActiveRoute 'UserManagement'}}">
|
<li class="{{isActiveRoute 'UserManagement'}}">
|
||||||
<a href="{{pathFor 'UserManagement'}}">
|
<a href="{{pathFor 'UserManagement'}}">
|
||||||
Users
|
Users
|
||||||
|
|||||||
67
imports/ui/styles/snapTable.import.styl
vendored
Normal file
67
imports/ui/styles/snapTable.import.styl
vendored
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
|
||||||
|
// A snap table is an abstraction of a full page table that I use repeatedly in projects. All of the table dialogs (editing, new, details, functions, etc) are embedded in the table its self.
|
||||||
|
// A basic table will have a load more link in the controls, and will load a fixed number of values. A scroll bar attached to the table contents will provide means of accessing all the data.
|
||||||
|
// The table header will be separated (in a separate HTML table) such that it is always visible.
|
||||||
|
// Often an action column will be in the mix to provide buttons related to the row, or if in the header will be an action on the table (such as a + button for adding new rows).
|
||||||
|
.snapTable
|
||||||
|
display table
|
||||||
|
content-box border-box
|
||||||
|
padding 10px 20px
|
||||||
|
height 100%
|
||||||
|
width 100%
|
||||||
|
text-align left
|
||||||
|
position relative
|
||||||
|
|
||||||
|
.tableControls
|
||||||
|
display table
|
||||||
|
width 100%
|
||||||
|
text-align right
|
||||||
|
margin-right 20px
|
||||||
|
a
|
||||||
|
font-size 12px
|
||||||
|
font-family "Arial", san-serif
|
||||||
|
font-weight 800
|
||||||
|
color #2d1b8c
|
||||||
|
text-decoration none
|
||||||
|
a:hover
|
||||||
|
text-decoration underline
|
||||||
|
a.disabled
|
||||||
|
visibility hidden
|
||||||
|
.table
|
||||||
|
table-layout fixed
|
||||||
|
min-width 100%
|
||||||
|
tr.selected
|
||||||
|
background-color #feff00
|
||||||
|
.separatedTableHeader
|
||||||
|
.actions
|
||||||
|
text-align center
|
||||||
|
.listContainer
|
||||||
|
position absolute
|
||||||
|
top 100px
|
||||||
|
left 0
|
||||||
|
right 0
|
||||||
|
bottom 0
|
||||||
|
.listRow
|
||||||
|
display table-row
|
||||||
|
.listCell
|
||||||
|
display table-cell
|
||||||
|
position relative
|
||||||
|
height 100%
|
||||||
|
width 100%
|
||||||
|
.tableContainer
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
bottom 0
|
||||||
|
left 0
|
||||||
|
right 0
|
||||||
|
width auto
|
||||||
|
height auto
|
||||||
|
border 0
|
||||||
|
font-size 12.5px
|
||||||
|
overflow-y auto
|
||||||
|
table
|
||||||
|
table-layout fixed
|
||||||
|
width 100%
|
||||||
|
thead
|
||||||
|
display none
|
||||||
|
visibility hidden
|
||||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "PetitTeton",
|
"name": "AVEF",
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "PetitTeton",
|
"name": "AVEF",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "meteor run",
|
"start": "meteor run",
|
||||||
|
|||||||
Reference in New Issue
Block a user