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:
Wynne Crisman
2020-01-16 09:32:59 -08:00
parent 3b1c57e47e
commit 9d243850db
15 changed files with 364 additions and 30 deletions

View 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
View 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

View 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.
}
});

View File

@@ -45,6 +45,11 @@
News & Notices
</a>
</li>
<li class="{{isActiveRoute 'Messages'}}">
<a href="{{pathFor 'Messages'}}">
Messages
</a>
</li>
<li class="{{isActiveRoute 'UserManagement'}}">
<a href="{{pathFor 'UserManagement'}}">
Users

67
imports/ui/styles/snapTable.import.styl vendored Normal file
View 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