Changed look of donut chart legend

Fixed deleteCampaign tooltip
Moved Result Status styles to an object
Dashboard, Users,  now has fancy loading gif
Now only loading ckeditor from templates and landing pages templates
Starting to add maps (coming soon!)
pull/24/head
unknown 2015-08-11 21:12:09 -05:00
parent 37a8883be1
commit a78e92a436
13 changed files with 133 additions and 123 deletions

36
static/css/main.css vendored
View File

@ -255,11 +255,10 @@
} }
.chartist-legend li { .chartist-legend li {
display: block; display: block;
padding-left: 30px;
position: relative; position: relative;
margin-bottom: 4px; margin-bottom: 4px;
border-radius: 5px; border-radius: 5px;
padding: 2px 8px 2px 28px; padding: 2px 8px 2px 8px;
font-size: 14px; font-size: 14px;
cursor: default; cursor: default;
-webkit-transition: background-color 200ms ease-in-out; -webkit-transition: background-color 200ms ease-in-out;
@ -268,13 +267,12 @@
transition: background-color 200ms ease-in-out; transition: background-color 200ms ease-in-out;
} }
.chartist-legend li span { .chartist-legend li span {
display: block; display: inline-block;
position: absolute; vertical-align:middle;
left: 0;
top: 0;
width: 20px; width: 20px;
height: 100%; height: 20px;
border-radius: 5px; margin-right:10px;
border-radius: 50%;
} }
.ct-series-a .ct-slice-donut { .ct-series-a .ct-slice-donut {
@ -285,16 +283,32 @@
stroke:#6c7a89 !important; stroke:#6c7a89 !important;
} }
.ct-slice-donut.ct-slice-donut-sent{
stroke:#1abc9c !important
}
.ct-slice-donut.ct-slice-donut-opened{
stroke:#eb9532 !important;
}
.ct-slice-donut.ct-slice-donut-success{ .ct-slice-donut.ct-slice-donut-success{
stroke:#f05b4f !important; stroke:#f05b4f !important;
} }
.ct-slice-donut.ct-slice-donut-clicked{
stroke:#f05b4f !important;
}
.ct-legend-error {
background-color: #6c7a89 !important;
}
.ct-legend-sent { .ct-legend-sent {
background-color: #1abc9c !important; background-color: #1abc9c !important;
} }
.ct-legend-error { .ct-legend-opened {
background-color: #6c7a89 !important; background-color: #eb9532 !important;
} }
.ct-legend-success { .ct-legend-success {
@ -302,5 +316,5 @@
} }
.ct-legend-clicked { .ct-legend-clicked {
background-color: #eb9532 !important; background-color: #f05b4f !important;
} }

View File

@ -1,29 +1,31 @@
// labels is a map of campaign statuses to var map = null
// CSS classes
var labels = {
"Email Sent" : "label-primary",
"Email Opened" : "label-info",
"Clicked Link" : "label-success",
"Error" : "label-danger"
}
// // statuses is a helper map to point result statuses to ui classes
var classes = { var statuses = {
"Email Sent" : { "Email Sent" : {
slice: "ct-slice-donut-sent", slice: "ct-slice-donut-sent",
legend: "ct-legend-sent" legend: "ct-legend-sent",
label: "label-success"
}, },
"Email Opened" : { "Email Opened" : {
slice: "ct-slice-donut-opened", slice: "ct-slice-donut-opened",
legend: "ct-legend-opened" legend: "ct-legend-opened",
label: "label-warning"
}, },
"Clicked Link" : { "Clicked Link" : {
slice: "ct-slice-donut-clicked", slice: "ct-slice-donut-clicked",
legend: "ct-legend-clicked" legend: "ct-legend-clicked",
label: "label-danger"
},
"Success" : {
slice: "ct-slice-donut-clicked",
legend: "ct-legend-clicked",
label: "label-danger"
}, },
"Error" : { "Error" : {
slice: "ct-slice-donut-error", slice: "ct-slice-donut-error",
legend: "ct-legend-error" legend: "ct-legend-error",
label: "label-default"
} }
} }
@ -57,6 +59,8 @@ $(document).ready(function(){
if (campaign){ if (campaign){
// Set the title // Set the title
$("#page-title").text("Results for " + c.name) $("#page-title").text("Results for " + c.name)
// Setup tooltips
$('[data-toggle="tooltip"]').tooltip()
// Setup our graphs // Setup our graphs
var timeline_data = {series:[{ var timeline_data = {series:[{
name: "Events", name: "Events",
@ -92,7 +96,7 @@ $(document).ready(function(){
// Setup the results table // Setup the results table
resultsTable = $("#resultsTable").DataTable(); resultsTable = $("#resultsTable").DataTable();
$.each(campaign.results, function(i, result){ $.each(campaign.results, function(i, result){
label = labels[result.status] || "label-default"; label = statuses[result.status].label || "label-default";
resultsTable.row.add([ resultsTable.row.add([
result.first_name || "", result.first_name || "",
result.last_name || "", result.last_name || "",
@ -108,10 +112,8 @@ $(document).ready(function(){
}) })
// Setup the graphs // Setup the graphs
$.each(campaign.timeline, function(i, event){ $.each(campaign.timeline, function(i, event){
console.log(moment(event.time).format('MMMM Do YYYY h:mm'))
timeline_data.series[0].data.push({meta : i, x: new Date(event.time), y:1}) timeline_data.series[0].data.push({meta : i, x: new Date(event.time), y:1})
}) })
console.log(timeline_data)
$.each(email_series_data, function(status, count){ $.each(email_series_data, function(status, count){
email_data.series.push({meta: status, value: count}) email_data.series.push({meta: status, value: count})
}) })
@ -146,10 +148,10 @@ $(document).ready(function(){
// We don't want to create the legend twice // We don't want to create the legend twice
if (!email_legend[data.meta]) { if (!email_legend[data.meta]) {
console.log(data.meta) console.log(data.meta)
$("#email_chart_legend").append('<li><span class="' + classes[data.meta].legend + '"></span>' + data.meta + '</li>') $("#email_chart_legend").append('<li><span class="' + statuses[data.meta].legend + '"></span>' + data.meta + '</li>')
email_legend[data.meta] = true email_legend[data.meta] = true
} }
data.element.addClass(classes[data.meta].slice) data.element.addClass(statuses[data.meta].slice)
}) })
// Setup the average chart listeners // Setup the average chart listeners
$piechart = $("#email_chart") $piechart = $("#email_chart")
@ -177,6 +179,24 @@ $(document).ready(function(){
$("#loading").hide() $("#loading").hide()
$("#campaignResults").show() $("#campaignResults").show()
} }
// Load up the map data (only once!)
// Slated for 0.2 release - coming soon! :)
// $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
// if ($(e.target).attr('href') == "#plugins"){
// if (!map){
// map = new Datamap({
// element: document.getElementById("resultsMap"),
// responsive: true,
// fills: {
// defaultFill: "#34495e"
// },
// geographyConfig: {
// highlightFillColor : "#1abc9c"
// }
// });
// }
// }
// })
}) })
.error(function(){ .error(function(){
errorFlash(" Campaign not found!") errorFlash(" Campaign not found!")

View File

@ -3,8 +3,10 @@ var campaigns = []
$(document).ready(function(){ $(document).ready(function(){
api.campaigns.get() api.campaigns.get()
.success(function(cs){ .success(function(cs){
$("#loading").hide()
campaigns = cs campaigns = cs
if (campaigns.length > 0){ if (campaigns.length > 0){
$("#dashboard").show()
// Create the overview chart data // Create the overview chart data
var overview_data = {labels:[],series:[[]]} var overview_data = {labels:[],series:[[]]}
var average_data = {series:[]} var average_data = {series:[]}
@ -22,8 +24,6 @@ $(document).ready(function(){
showLabel: false showLabel: false
} }
var average = 0 var average = 0
$("#emptyMessage").hide()
$("#campaignTable").show()
campaignTable = $("#campaignTable").DataTable(); campaignTable = $("#campaignTable").DataTable();
$.each(campaigns, function(i, campaign){ $.each(campaigns, function(i, campaign){
var campaign_date = moment(campaign.created_date).format('MMMM Do YYYY h:mm') var campaign_date = moment(campaign.created_date).format('MMMM Do YYYY h:mm')
@ -31,7 +31,13 @@ $(document).ready(function(){
campaignTable.row.add([ campaignTable.row.add([
campaign.name, campaign.name,
campaign_date, campaign_date,
campaign.status campaign.status,
"<div class='pull-right'><a class='btn btn-primary' href='/campaigns/" + campaign.id + "'>\
<i class='fa fa-bar-chart'></i>\
</a>\
<button class='btn btn-danger' onclick='deleteCampaign(" + i + ")'>\
<i class='fa fa-trash-o'></i>\
</button></div>"
]).draw() ]).draw()
// Add it to the chart data // Add it to the chart data
campaign.y = 0 campaign.y = 0
@ -103,6 +109,8 @@ $(document).ready(function(){
var $cidx = $(this).attr('ct:meta'); var $cidx = $(this).attr('ct:meta');
window.location.href = "/campaigns/" + campaigns[cidx].id window.location.href = "/campaigns/" + campaigns[cidx].id
}); });
} else {
$("#emptyMessage").show()
} }
}) })
.error(function(){ .error(function(){

View File

@ -109,10 +109,14 @@ function deleteGroup(idx){
} }
function load(){ function load(){
$("#groupTable").hide()
$("#emptyMessage").hide()
$("#loading").show()
api.groups.get() api.groups.get()
.success(function(gs){ .success(function(gs){
if (gs.length > 0){ if (gs.length > 0){
groups = gs groups = gs
$("#emptyMessage").hide()
$("#loading").hide() $("#loading").hide()
$("#groupTable").show() $("#groupTable").show()
groupTable = $("#groupTable").DataTable(); groupTable = $("#groupTable").DataTable();
@ -138,6 +142,9 @@ function load(){
</button></div>" </button></div>"
]).draw() ]).draw()
}) })
} else {
$("#loading").hide()
$("#emptyMessage").show()
} }
}) })
.error(function(){ .error(function(){

5
static/js/d3.min.js vendored Normal file

File diff suppressed because one or more lines are too long

2
static/js/datamaps.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
static/js/topojson.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -91,8 +91,6 @@
<script src="/js/dataTables.bootstrap.js"></script> <script src="/js/dataTables.bootstrap.js"></script>
<script src="/js/chartist.min.js"></script> <script src="/js/chartist.min.js"></script>
<script src="/js/moment.min.js"></script> <script src="/js/moment.min.js"></script>
<script src="/js/ckeditor/ckeditor.js"></script>
<script src="/js/ckeditor/adapters/jquery.js"></script>
<script src="/js/gophish.js"></script> <script src="/js/gophish.js"></script>
{{template "scripts" .}} {{template "scripts" .}}
</body> </body>

View File

@ -50,8 +50,8 @@
<div class="row"> <div class="row">
<ul class="nav nav-tabs" role="tablist"> <ul class="nav nav-tabs" role="tablist">
<li class="active"><a href="#overview" aria-controls="home" role="tab" data-toggle="tab">Overview</a></li> <li class="active"><a href="#overview" aria-controls="home" role="tab" data-toggle="tab">Overview</a></li>
<li><a href="#plugins" aria-controls="profile" role="tab" data-toggle="tab">Plugins</a></li> <!-- <li><a href="#plugins" aria-controls="profile" role="tab" data-toggle="tab">Plugins</a></li>
<li><a href="#demographics" aria-controls="settings" role="tab" data-toggle="tab">Demographics</a></li> <li><a href="#demographics" aria-controls="settings" role="tab" data-toggle="tab">Demographics</a></li> -->
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="overview"> <div role="tabpanel" class="tab-pane active" id="overview">
@ -72,12 +72,16 @@
</div> </div>
</div> </div>
</div> </div>
<div role="tabpanel" class="tab-pane" id="plugins"> <!-- <div role="tabpanel" class="tab-pane" id="plugins">
Plugins here <div class="row">
<div class="col-md-8">
<div id="resultsMap"></div>
</div>
</div>
</div> </div>
<div role="tabpanel" class="tab-pane" id="demographics"> <div role="tabpanel" class="tab-pane" id="demographics">
Demographics here Demographics here
</div> </div> -->
</div> </div>
</div> </div>
<div class="row"> <div class="row">
@ -102,5 +106,9 @@
{{end}} {{end}}
{{define "scripts"}} {{define "scripts"}}
<script src="/js/jquery.ui.widget.js"></script> <script src="/js/jquery.ui.widget.js"></script>
<!-- d3, topojson, and datamaps for mapping -->
<script src="/js/d3.min.js"></script>
<script src="/js/topojson.min.js"></script>
<script src="/js/datamaps.min.js"></script>
<script src="/js/app/campaign_results.js"></script> <script src="/js/app/campaign_results.js"></script>
{{end}} {{end}}

View File

@ -25,12 +25,15 @@
<h1 class="page-header"> <h1 class="page-header">
Dashboard Dashboard
</h1> </h1>
<div id="emptyMessage" class="row"> <div id="loading">
<i class="fa fa-spinner fa-spin fa-4x"></i>
</div>
<div id="emptyMessage" class="row" style="display:none;">
<div class="alert alert-info"> <div class="alert alert-info">
No campaigns created yet. Let's create one! No campaigns created yet. Let's create one!
</div> </div>
</div> </div>
<div> <div id="dashboard" style="display:none;">
<div class="row"> <div class="row">
<div id="overview_chart" class="col-lg-6 col-md-6 col-sm-12 col-xs-12"> <div id="overview_chart" class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
<p style="text-align:center;">Phishing Success Overview</p> <p style="text-align:center;">Phishing Success Overview</p>
@ -58,37 +61,13 @@
</div> </div>
&nbsp;&nbsp; &nbsp;&nbsp;
<div class="row"> <div class="row">
<!-- <table ng-table="mainTableParams" class="table table-hover table-striped table-bordered"> <table id="campaignTable" class="table">
<tbody>
<tr ng-repeat="campaign in $data" class="editable-row">
<td data-title="'Created Date'" class="col-sm-1">campaign.created_date | date:'medium'</td>
<td data-title="'Name'" class="col-sm-2">campaign.name
<div class="btn-group" style="float: right;">
<button type="button" class="btn btn-primary dropdown-toggle edit-button" data-toggle="dropdown">
<span class="caret" style="border-top-color:#FFFFFF"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" style="left:auto; right:0;" role="menu">
<li><a ng-href="#/campaigns/campaign.id">View</a>
</li>
<li><a href="/campaigns/campaign.id/relaunch">Relaunch</a>
</li>
<li class="divider"></li>
<li><a ng-click="deleteCampaign(campaign)" ng-href="#">Delete</a>
</li>
</ul>
</div>
</td>
<td data-title="'Status'" class="col-sm-1">campaign.status</td>
</tr>
</tbody>
</table> -->
<table id="campaignTable" class="table" style="display:none;">
<thead> <thead>
<tr> <tr>
<th>Name</th> <th>Name</th>
<th>Created Date</th> <th>Created Date</th>
<th>Status</th> <th>Status</th>
<th class="col-md-2 col-sm-2"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -1,3 +1,4 @@
{{define "body"}}
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-sm-3 col-md-2 sidebar"> <div class="col-sm-3 col-md-2 sidebar">
@ -20,48 +21,41 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main" ng-controller="LandingPageCtrl"> <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h1 class="page-header"> <h1 class="page-header">
Landing Pages Landing Pages
</h1> </h1>
<div class="row"> <div id="flashes" class="row"></div>
<div ng-repeat="flash in flashes" style="text-align:center" class="alert alert-{{flash.type}}">
<i class="fa {{flash.icon}}"></i> {{flash.message}}
</div>
</div>
<div class="row"> <div class="row">
<button type="button" class="btn btn-primary" ng-click="editPage('new')" data-toggle="modal" data-target="#newLandingPageModal"><i class="fa fa-plus"></i> New Page</button> <button type="button" class="btn btn-primary" ng-click="editPage('new')" data-toggle="modal" data-target="#newLandingPageModal"><i class="fa fa-plus"></i> New Page</button>
</div> </div>
&nbsp; &nbsp;
<div ng-show="!pages.length"> <div id="loading">
<i class="fa fa-spinner fa-spin fa-4x"></i>
</div>
<div style="display:none;">
<div class="row"> <div class="row">
<div class="alert alert-info"> <div class="alert alert-info">
No pages created yet. Let's create one! No pages created yet. Let's create one!
</div> </div>
</div> </div>
</div> </div>
<div ng-show="pages.length" class="row"> <div class="row">
<table ng-table="mainTableParams" class="table table-hover table-striped table-bordered"> <table id="pagesTable" class="table" style="display:none;">
<tbody> <thead>
<tr ng-repeat="page in $data | orderBy: '-modified_date'" class="editable-row"> <tr>
<td data-title="'Name'" sortable="'name'" class="col-sm-2">{{page.name}} <th>Name</th>
<div class="btn-group" style="float: right;"> <th>Last Modified Date</th>
<button type="button" class="btn btn-primary dropdown-toggle edit-button" data-toggle="dropdown"> <th class="col-md-2"></th>
<span class="caret" style="border-top-color:#FFFFFF"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" style="left:auto; right:0;" role="menu">
<li><a ng-click="editPage(page)">Edit</a>
</li>
<li class="divider"></li>
<li><a ng-click="deletePage(page)" ng-href="#">Delete</a>
</li>
</ul>
</div>
</td>
<td data-title="'Modified Date'" class="col-sm-1">{{page.modified_date | date:'medium'}}</td>
</tr> </tr>
</thead>
<tbody>
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
{{end}}
{{define "scripts"}}
<script src="/js/ckeditor/ckeditor.js"></script>
<script src="/js/ckeditor/adapters/jquery.js"></script>
{{end}}

View File

@ -139,5 +139,7 @@
</div> </div>
{{end}} {{end}}
{{define "scripts"}} {{define "scripts"}}
<script src="/js/ckeditor/ckeditor.js"></script>
<script src="/js/ckeditor/adapters/jquery.js"></script>
<script src="/js/app/templates.js"></script> <script src="/js/app/templates.js"></script>
{{end}} {{end}}

View File

@ -54,34 +54,6 @@
</tbody> </tbody>
</table> </table>
</div> </div>
<!-- <div ng-show="groups.length" class="row">
<table ng-table="mainTableParams" class="table table-hover table-striped table-bordered">
<tbody>
<tr ng-repeat="group in $data | orderBy: '-modified_date'" class="editable-row">
<td data-title="'Name'" sortable="'name'" class="col-sm-1">group.name</td>
<td data-title="'Members'" class="col-sm-2">
<span ng-repeat="target in group.targets | cut:5 track by $index ">
target$last ? '' : ', '
</span>
<div class="btn-group" style="float: right;">
<button type="button" class="btn btn-primary dropdown-toggle edit-button" data-toggle="dropdown">
<span class="caret" style="border-top-color:#FFFFFF"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" style="left:auto; right:0;" role="menu">
<li><a ng-click="editGroup(group)">Edit</a>
</li>
<li class="divider"></li>
<li><a ng-click="deleteGroup(group)">Delete</a>
</li>
</ul>
</div>
</td>
<td data-title="'Modified Date'" class="col-sm-1">group.modified_date | date:'medium'</td>
</tr>
</tbody>
</table>
</div> -->
</div> </div>
<!-- Modal --> <!-- Modal -->
<div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="modalLabel"> <div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="modalLabel">