Updated dashboard to show full final statuses instead of just "Successful" vs "Unsuccessful".

pull/662/head
Jordan Wright 2017-06-18 17:32:18 -05:00
parent 269568148e
commit 80c68194a6
3 changed files with 183 additions and 86 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,12 +1,89 @@
var campaigns = [] var campaigns = []
// labels is a map of campaign statuses to
// CSS classes // statuses is a helper map to point result statuses to ui classes
var labels = { var statuses = {
"In progress": "label-primary", "Email Sent": {
"Queued": "label-info", slice: "ct-slice-donut-sent",
"Completed": "label-success", legend: "ct-legend-sent",
"Emails Sent": "label-success", label: "label-success",
"Error": "label-danger" icon: "fa-envelope",
point: "ct-point-sent"
},
"Email Sent": {
slice: "ct-slice-donut-sent",
legend: "ct-legend-sent",
label: "label-success",
icon: "fa-envelope",
point: "ct-point-sent"
},
"Email Opened": {
slice: "ct-slice-donut-opened",
legend: "ct-legend-opened",
label: "label-warning",
icon: "fa-envelope",
point: "ct-point-opened"
},
"Clicked Link": {
slice: "ct-slice-donut-clicked",
legend: "ct-legend-clicked",
label: "label-clicked",
icon: "fa-mouse-pointer",
point: "ct-point-clicked"
},
"Success": {
slice: "ct-slice-donut-success",
legend: "ct-legend-success",
label: "label-danger",
icon: "fa-exclamation",
point: "ct-point-clicked"
},
"Error": {
slice: "ct-slice-donut-error",
legend: "ct-legend-error",
label: "label-default",
icon: "fa-times",
point: "ct-point-error"
},
"Error Sending Email": {
slice: "ct-slice-donut-error",
legend: "ct-legend-error",
label: "label-default",
icon: "fa-times",
point: "ct-point-error"
},
"Submitted Data": {
slice: "ct-slice-donut-success",
legend: "ct-legend-success",
label: "label-danger",
icon: "fa-exclamation",
point: "ct-point-clicked"
},
"Unknown": {
slice: "ct-slice-donut-error",
legend: "ct-legend-error",
label: "label-default",
icon: "fa-question",
point: "ct-point-error"
},
"Sending": {
slice: "ct-slice-donut-sending",
legend: "ct-legend-sending",
label: "label-primary",
icon: "fa-spinner",
point: "ct-point-sending"
},
"Campaign Created": {
label: "label-success",
icon: "fa-rocket"
}
}
var statsMapping = {
"sent": "Email Sent",
"opened": "Email Opened",
"clicked": "Clicked Link",
"submitted_data": "Submitted Data",
"error": "Error"
} }
function deleteCampaign(idx) { function deleteCampaign(idx) {
@ -19,6 +96,75 @@ function deleteCampaign(idx) {
} }
} }
function generateStatsPieChart(campaigns) {
var stats_opts = {
donut: true,
donutWidth: 40,
chartPadding: 0,
showLabel: false
}
var stats_series_data = {}
var stats_data = {
series: []
}
var total = 0
$.each(campaigns, function(i, campaign) {
$.each(campaign.stats, function(status, count) {
if (status == "total") {
total += count
return true
}
if (!stats_series_data[status]) {
stats_series_data[status] = count;
} else {
stats_series_data[status] += count;
}
})
})
$.each(stats_series_data, function(status, count) {
// I don't like this, but I guess it'll have to work.
// Turns submitted_data into Submitted Data
status_label = statsMapping[status]
stats_data.series.push({
meta: status_label,
value: Math.floor((count / total) * 100)
})
$("#stats_chart_legend").append('<li><span class="' + statuses[status_label].legend + '"></span>' + status_label + '</li>')
})
var stats_chart = new Chartist.Pie("#stats_chart", stats_data, stats_opts)
$piechart = $("#stats_chart")
var $pietoolTip = $piechart
.append('<div class="chartist-tooltip"></div>')
.find('.chartist-tooltip')
.hide();
$piechart.get(0).__chartist__.on('draw', function(data) {
data.element.addClass(statuses[data.meta].slice)
})
// Update with the latest data
$piechart.get(0).__chartist__.update(stats_data)
$piechart.on('mouseenter', '.ct-slice-donut', function() {
var $point = $(this)
value = $point.attr('ct:value')
label = $point.attr('ct:meta')
$pietoolTip.html(label + ': ' + value.toString() + "%").show();
});
$piechart.on('mouseleave', '.ct-slice-donut', function() {
$pietoolTip.hide();
});
$piechart.on('mousemove', function(event) {
$pietoolTip.css({
left: (event.offsetX || event.originalEvent.layerX) - $pietoolTip.width() / 2 - 10,
top: (event.offsetY + 40 || event.originalEvent.layerY) - $pietoolTip.height() - 80
});
});
}
$(document).ready(function() { $(document).ready(function() {
api.campaigns.summary() api.campaigns.summary()
.success(function(data) { .success(function(data) {
@ -33,9 +179,6 @@ $(document).ready(function() {
[] []
] ]
} }
var average_data = {
series: []
}
var overview_opts = { var overview_opts = {
axisX: { axisX: {
showGrid: false showGrid: false
@ -45,13 +188,6 @@ $(document).ready(function() {
low: 0, low: 0,
high: 100 high: 100
} }
var average_opts = {
donut: true,
donutWidth: 40,
chartPadding: 0,
showLabel: false
}
var average = 0
campaignTable = $("#campaignTable").DataTable({ campaignTable = $("#campaignTable").DataTable({
columnDefs: [{ columnDefs: [{
orderable: false, orderable: false,
@ -62,19 +198,19 @@ $(document).ready(function() {
] ]
}); });
$.each(campaigns, function(i, campaign) { $.each(campaigns, function(i, campaign) {
var campaign_date = moment(campaign.created_date).format('MMMM Do YYYY, h:mm:ss a') var campaign_date = moment(campaign.created_date).format('MMMM Do YYYY, h:mm:ss a')
var label = labels[campaign.status] || "label-default"; var label = statuses[campaign.status] || "label-default";
//section for tooltips on the status of a campaign to show some quick stats //section for tooltips on the status of a campaign to show some quick stats
var launchDate; var launchDate;
if (moment(campaign.launch_date).isAfter(moment())) { if (moment(campaign.launch_date).isAfter(moment())) {
launchDate = "Scheduled to start: " + moment(campaign.launch_date).format('MMMM Do YYYY, h:mm:ss a') launchDate = "Scheduled to start: " + moment(campaign.launch_date).format('MMMM Do YYYY, h:mm:ss a')
var quickStats = launchDate + "<br><br>" + "Number of recipients: " + campaign.stats.total var quickStats = launchDate + "<br><br>" + "Number of recipients: " + campaign.stats.total
} else { } else {
launchDate = "Launch Date: " + moment(campaign.launch_date).format('MMMM Do YYYY, h:mm:ss a') launchDate = "Launch Date: " + moment(campaign.launch_date).format('MMMM Do YYYY, h:mm:ss a')
var quickStats = launchDate + "<br><br>" + "Number of recipients: " + campaign.stats.total + "<br><br>" + "Emails opened: " + campaign.stats.opened + "<br><br>" + "Emails clicked: " + campaign.stats.clicked + "<br><br>" + "Submitted Credentials: " + campaign.stats.submitted_data + "<br><br>" + "Errors : " + campaign.stats.error var quickStats = launchDate + "<br><br>" + "Number of recipients: " + campaign.stats.total + "<br><br>" + "Emails opened: " + campaign.stats.opened + "<br><br>" + "Emails clicked: " + campaign.stats.clicked + "<br><br>" + "Submitted Credentials: " + campaign.stats.submitted_data + "<br><br>" + "Errors : " + campaign.stats.error
} }
// Add it to the table // Add it to the table
campaignTable.row.add([ campaignTable.row.add([
escapeHtml(campaign.name), escapeHtml(campaign.name),
campaign_date, campaign_date,
"<span class=\"label " + label + "\" data-toggle=\"tooltip\" data-placement=\"right\" data-html=\"true\" title=\"" + quickStats + "\">" + campaign.status + "</span>", "<span class=\"label " + label + "\" data-toggle=\"tooltip\" data-placement=\"right\" data-html=\"true\" title=\"" + quickStats + "\">" + campaign.status + "</span>",
@ -85,54 +221,21 @@ $(document).ready(function() {
<i class='fa fa-trash-o'></i>\ <i class='fa fa-trash-o'></i>\
</button></div>" </button></div>"
]).draw() ]).draw()
$('[data-toggle="tooltip"]').tooltip() $('[data-toggle="tooltip"]').tooltip()
// Add it to the chart data // Add it to the chart data
campaign.y = 0 campaign.y = 0
campaign.y += campaign.stats.clicked + campaign.stats.submitted_data campaign.y += campaign.stats.clicked + campaign.stats.submitted_data
campaign.y = Math.floor((campaign.y / campaign.stats.total) * 100) campaign.y = Math.floor((campaign.y / campaign.stats.total) * 100)
average += campaign.y // Add the data to the overview chart
// Add the data to the overview chart overview_data.labels.push(campaign_date)
overview_data.labels.push(campaign_date) overview_data.series[0].push({
overview_data.series[0].push({ meta: i,
meta: i, value: campaign.y
value: campaign.y })
})
})
average = Math.floor(average / data.total);
average_data.series.push({
meta: "Unsuccessful Phishes",
value: 100 - average
})
average_data.series.push({
meta: "Successful Phishes",
value: average
}) })
// Build the charts // Build the charts
var average_chart = new Chartist.Pie("#average_chart", average_data, average_opts) generateStatsPieChart(campaigns)
var overview_chart = new Chartist.Line('#overview_chart', overview_data, overview_opts) var overview_chart = new Chartist.Line('#overview_chart', overview_data, overview_opts)
// Setup the average chart listeners
$piechart = $("#average_chart")
var $pietoolTip = $piechart
.append('<div class="chartist-tooltip"></div>')
.find('.chartist-tooltip')
.hide();
$piechart.on('mouseenter', '.ct-slice-donut', function() {
var $point = $(this)
value = $point.attr('ct:value')
label = $point.attr('ct:meta')
$pietoolTip.html(label + ': ' + value.toString() + "%").show();
});
$piechart.on('mouseleave', '.ct-slice-donut', function() {
$pietoolTip.hide();
});
$piechart.on('mousemove', function(event) {
$pietoolTip.css({
left: (event.offsetX || event.originalEvent.layerX) - $pietoolTip.width() / 2 - 10,
top: (event.offsetY + 40 || event.originalEvent.layerY) - $pietoolTip.height() - 80
});
});
// Setup the overview chart listeners // Setup the overview chart listeners
$chart = $("#overview_chart") $chart = $("#overview_chart")

View File

@ -45,15 +45,9 @@
</div> </div>
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12"> <div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
<p style="text-align:center;">Average Phishing Results</p> <p style="text-align:center;">Average Phishing Results</p>
<div id="average_chart" class="col-lg-7 col-md-7"></div> <div id="stats_chart" class="col-lg-7 col-md-7"></div>
<div id="average_chart_legend" class="col-lg-5 col-md-5"> <div class="col-lg-5 col-md-5">
<ul class="chartist-legend"> <ul id="stats_chart_legend" class="chartist-legend">
<li>
<span style="background-color:#f05b4f;"></span> Successful Phishes
</li>
<li>
<span style="background-color:#1abc9c;"></span> Unsuccessful Phishes
</li>
</ul> </ul>
</div> </div>
</div> </div>