This commit is contained in:
Andris Reinman 2016-05-13 21:08:44 +03:00
parent b626ea9c5e
commit 5b20ff2242
6 changed files with 142 additions and 34 deletions

View file

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

View file

@ -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": {

View file

@ -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);
});
}
});
});
});

View file

@ -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">

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

View file

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