v1.8.2
This commit is contained in:
parent
b626ea9c5e
commit
5b20ff2242
6 changed files with 142 additions and 34 deletions
|
@ -1,5 +1,9 @@
|
|||
# Changelog
|
||||
|
||||
## 1.8.2 2016-05-13
|
||||
|
||||
* Added missing views for subscribers who clicked on any link and subscribers who opened the message
|
||||
|
||||
## 1.8.1 2016-05-13
|
||||
|
||||
* Fixed an issue in API
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "mailtrain",
|
||||
"private": true,
|
||||
"version": "1.8.1",
|
||||
"version": "1.8.2",
|
||||
"description": "Self hosted email newsletter app",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
|
|
@ -348,6 +348,31 @@ router.get('/view/:id', passport.csrfProtection, (req, res) => {
|
|||
});
|
||||
});
|
||||
|
||||
router.get('/opened/:id', passport.csrfProtection, (req, res) => {
|
||||
campaigns.get(req.params.id, true, (err, campaign) => {
|
||||
if (err || !campaign) {
|
||||
req.flash('danger', err && err.message || err || 'Could not find campaign with specified ID');
|
||||
return res.redirect('/campaigns');
|
||||
}
|
||||
|
||||
lists.get(campaign.list, (err, list) => {
|
||||
if (err || !campaign) {
|
||||
req.flash('danger', err && err.message || err);
|
||||
return res.redirect('/campaigns');
|
||||
}
|
||||
|
||||
campaign.csrfToken = req.csrfToken();
|
||||
campaign.list = list;
|
||||
|
||||
// show only messages that weren't bounced as delivered
|
||||
campaign.delivered = campaign.delivered - campaign.bounced;
|
||||
campaign.clicksRate = campaign.delivered ? Math.round((campaign.clicks / campaign.delivered) * 100) : 0;
|
||||
|
||||
res.render('campaigns/opened', campaign);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/clicked/:id/:linkId', passport.csrfProtection, (req, res) => {
|
||||
campaigns.get(req.params.id, true, (err, campaign) => {
|
||||
if (err || !campaign) {
|
||||
|
@ -366,7 +391,15 @@ router.get('/clicked/:id/:linkId', passport.csrfProtection, (req, res) => {
|
|||
|
||||
// show only messages that weren't bounced as delivered
|
||||
campaign.delivered = campaign.delivered - campaign.bounced;
|
||||
campaign.clicksRate = campaign.delivered ? Math.round((campaign.clicks / campaign.delivered) * 100) : 0;
|
||||
|
||||
if (req.params.linkId === 'all') {
|
||||
campaign.aggregated = true;
|
||||
campaign.link = {
|
||||
id: 0
|
||||
};
|
||||
res.render('campaigns/clicked', campaign);
|
||||
} else {
|
||||
campaigns.getLinks(campaign.id, req.params.linkId, (err, links) => {
|
||||
if (err) {
|
||||
// ignore
|
||||
|
@ -382,10 +415,9 @@ router.get('/clicked/:id/:linkId', passport.csrfProtection, (req, res) => {
|
|||
}
|
||||
return link;
|
||||
}).shift();
|
||||
campaign.showOverview = true;
|
||||
res.render('campaigns/clicked', campaign);
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -34,6 +34,20 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
<tr class="success">
|
||||
{{#if aggregated}}
|
||||
<th>
|
||||
Aggregated clicks
|
||||
</th>
|
||||
<th>
|
||||
{{clicks}}
|
||||
</th>
|
||||
<th>
|
||||
–
|
||||
</th>
|
||||
<th>
|
||||
CTR {{clicksRate}}%
|
||||
</th>
|
||||
{{else}}
|
||||
<td>
|
||||
<a href="{{link.url}}">{{link.short}}</a>
|
||||
</td>
|
||||
|
@ -46,13 +60,14 @@
|
|||
<td>
|
||||
{{link.totalPercentage}}
|
||||
</td>
|
||||
{{/if}}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="panel panel-info">
|
||||
<!-- Default panel contents -->
|
||||
<div class="panel-heading">Subscribers who clicked on this link:</div>
|
||||
<div class="panel-heading">{{#if aggregated}}Subscribers who clicked on a link:{{else}}Subscribers who clicked on this link:{{/if}}</div>
|
||||
<div class="panel-body">
|
||||
<div class="table-responsive">
|
||||
<table data-topic-url="/campaigns/clicked" data-topic-id="{{id}}/{{link.id}}" data-sort-column="1" data-sort-order="asc" class="table table-bordered table-hover data-table-ajax display nowrap" width="100%" data-row-sort="0,1,1,1,1,1,0">
|
||||
|
|
54
views/campaigns/opened.hbs
Normal file
54
views/campaigns/opened.hbs
Normal file
|
@ -0,0 +1,54 @@
|
|||
<ol class="breadcrumb">
|
||||
<li><a href="/">Home</a></li>
|
||||
<li><a href="/campaigns">Campaigns</a></li>
|
||||
{{#if parent}}
|
||||
<li><a href="/campaigns/view/{{parent.id}}">{{parent.name}}</a></li>
|
||||
{{/if}}
|
||||
<li><a href="/campaigns/view/{{id}}">{{name}}</a></li>
|
||||
<li class="active">Opened info</li>
|
||||
</ol>
|
||||
|
||||
<h2><span class="glyphicon glyphicon-inbox" aria-hidden="true"></span> {{name}} <small>Opened info</small> <a class="btn btn-default btn-xs" href="/campaigns/view/{{id}}?tab=overview" role="button"><span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span> View campaign</a></h2>
|
||||
|
||||
<hr>
|
||||
|
||||
{{#if description}}
|
||||
<div class="well well-sm">{{{description}}}</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
<div class="panel panel-info">
|
||||
<!-- Default panel contents -->
|
||||
<div class="panel-heading">Subscribers who opened this message:</div>
|
||||
<div class="panel-body">
|
||||
<div class="table-responsive">
|
||||
<table data-topic-url="/campaigns/clicked" data-topic-id="{{id}}/-1" data-sort-column="1" data-sort-order="asc" class="table table-bordered table-hover data-table-ajax display nowrap" width="100%" data-row-sort="0,1,1,1,1,1,0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-md-1">
|
||||
#
|
||||
</th>
|
||||
<th>
|
||||
Address
|
||||
</th>
|
||||
<th>
|
||||
First Name
|
||||
</th>
|
||||
<th>
|
||||
Last Name
|
||||
</th>
|
||||
<th>
|
||||
First open
|
||||
</th>
|
||||
<th>
|
||||
Opened count
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -100,7 +100,7 @@
|
|||
<dt>Unsubscribed</dt>
|
||||
<dd>{{unsubscribed}}</dd>
|
||||
|
||||
<dt>Opened</dt>
|
||||
<dt>Opened <a href="/campaigns/opened/{{id}}" title="List subscribers who opened this message"><span class="glyphicon glyphicon-circle-arrow-right" aria-hidden="true"></span></a></dt>
|
||||
<dd>
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="{{openRate}}" aria-valuemin="0" aria-valuemax="100" style="min-width: 2em; width: {{openRate}}%;">
|
||||
|
@ -109,7 +109,7 @@
|
|||
</div>
|
||||
</dd>
|
||||
|
||||
<dt>Clicked</dt>
|
||||
<dt>Clicked <a href="/campaigns/clicked/{{id}}/all" title="List subscribers who clicked on a link"><span class="glyphicon glyphicon-circle-arrow-right" aria-hidden="true"></span></a></dt>
|
||||
<dd>
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="{{clicksRate}}" aria-valuemin="0" aria-valuemax="100" style="min-width: 2em; width: {{clicksRate}}%;">
|
||||
|
@ -322,6 +322,9 @@
|
|||
Aggregated clicks
|
||||
</th>
|
||||
<th>
|
||||
<div class="pull-right">
|
||||
<a href="/campaigns/clicked/{{id}}/all" title="List subscribers who clicked on a link"><span class="glyphicon glyphicon-circle-arrow-right" aria-hidden="true"></span></a>
|
||||
</div>
|
||||
{{clicks}}
|
||||
</th>
|
||||
<th>
|
||||
|
|
Loading…
Reference in a new issue