From 1fafe4845fd07c405e7ae79e6d16fd1798523d37 Mon Sep 17 00:00:00 2001 From: Jordan Wright Date: Thu, 27 Apr 2017 18:54:33 -0500 Subject: [PATCH] Adding quick stats tooltips (#607) * Adding a quick stats popup to campaign page (#600) Added quick stats popup to campaign page * Adding summarized quick stat tooltips on dashboard --- static/js/dist/app/campaigns.min.js | 2 +- static/js/dist/app/dashboard.min.js | 2 +- static/js/src/app/campaigns.js | 13 ++++++++++++- static/js/src/app/dashboard.js | 16 +++++++++++++--- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/static/js/dist/app/campaigns.min.js b/static/js/dist/app/campaigns.min.js index 8f2606d1..b3dbd113 100644 --- a/static/js/dist/app/campaigns.min.js +++ b/static/js/dist/app/campaigns.min.js @@ -1 +1 @@ -function launch(){swal({title:"Are you sure?",text:"This will schedule the campaign to be launched.",type:"question",animation:!1,showCancelButton:!0,confirmButtonText:"Launch",confirmButtonColor:"#428bca",reverseButtons:!0,allowOutsideClick:!1,showLoaderOnConfirm:!0,preConfirm:function(){return new Promise(function(e,a){groups=[],$("#users").select2("data").forEach(function(e){groups.push({name:e.text})}),campaign={name:$("#name").val(),template:{name:$("#template").select2("data")[0].text},url:$("#url").val(),page:{name:$("#page").select2("data")[0].text},smtp:{name:$("#profile").select2("data")[0].text},launch_date:moment($("#launch_date").val(),"MM/DD/YYYY hh:mm a").format(),groups:groups},api.campaigns.post(campaign).success(function(a){e(),campaign=a}).error(function(e){$("#modal\\.flashes").empty().append('
'+e.responseJSON.message+"
"),swal.close()})})}}).then(function(){swal("Campaign Scheduled!","This campaign has been scheduled for launch!","success"),$('button:contains("OK")').on("click",function(){window.location="/campaigns/"+campaign.id.toString()})})}function sendTestEmail(){var e={template:{name:$("#template").select2("data")[0].text},first_name:$("input[name=to_first_name]").val(),last_name:$("input[name=to_last_name]").val(),email:$("input[name=to_email]").val(),position:$("input[name=to_position]").val(),url:$("#url").val(),page:{name:$("#page").select2("data")[0].text},smtp:{name:$("#profile").select2("data")[0].text}};btnHtml=$("#sendTestModalSubmit").html(),$("#sendTestModalSubmit").html(' Sending'),api.send_test_email(e).success(function(e){$("#sendTestEmailModal\\.flashes").empty().append('
Email Sent!
'),$("#sendTestModalSubmit").html(btnHtml)}).error(function(e){$("#sendTestEmailModal\\.flashes").empty().append('
'+e.responseJSON.message+"
"),$("#sendTestModalSubmit").html(btnHtml)})}function dismiss(){$("#modal\\.flashes").empty(),$("#name").val(""),$("#template").val("").change(),$("#page").val("").change(),$("#url").val(""),$("#profile").val("").change(),$("#users").val("").change(),$("#modal").modal("hide")}function deleteCampaign(e){swal({title:"Are you sure?",text:"This will delete the campaign. This can't be undone!",type:"warning",animation:!1,showCancelButton:!0,confirmButtonText:"Delete "+campaigns[e].name,confirmButtonColor:"#428bca",reverseButtons:!0,allowOutsideClick:!1,preConfirm:function(){return new Promise(function(a,t){api.campaignId.delete(campaigns[e].id).success(function(e){a()}).error(function(e){t(e.responseJSON.message)})})}}).then(function(){swal("Campaign Deleted!","This campaign has been deleted!","success"),$('button:contains("OK")').on("click",function(){location.reload()})})}function setupOptions(){api.groups.get().success(function(e){if(0==e.length)return modalError("No groups found!"),!1;var a=$.map(e,function(e){return e.text=e.name,e});$("#users.form-control").select2({placeholder:"Select Groups",data:a})}),api.templates.get().success(function(e){if(0==e.length)return modalError("No templates found!"),!1;var a=$.map(e,function(e){return e.text=e.name,e});$("#template.form-control").select2({placeholder:"Select a Template",data:a})}),api.pages.get().success(function(e){if(0==e.length)return modalError("No pages found!"),!1;var a=$.map(e,function(e){return e.text=e.name,e});$("#page.form-control").select2({placeholder:"Select a Landing Page",data:a})}),api.SMTP.get().success(function(e){if(0==e.length)return modalError("No profiles found!"),!1;var a=$.map(e,function(e){return e.text=e.name,e});$("#profile.form-control").select2({placeholder:"Select a Sending Profile",data:a})})}function edit(e){setupOptions()}function copy(e){setupOptions(),api.campaignId.get(campaigns[e].id).success(function(e){$("#name").val("Copy of "+e.name),e.template.id?$("#template").select2("val",e.template.id.toString()):$("#template").select2({placeholder:e.template.name}),e.page.id?$("#page").select2("val",e.page.id.toString()):$("#page").select2({placeholder:e.page.name}),e.smtp.id?$("#profile").select2("val",e.smtp.id.toString()):$("#profile").select2({placeholder:e.smtp.name}),$("#url").val(e.url)}).error(function(e){$("#modal\\.flashes").empty().append('
'+e.responseJSON.message+"
")})}var labels={"In progress":"label-primary",Queued:"label-info",Completed:"label-success","Emails Sent":"label-success",Error:"label-danger"},campaigns=[],campaign={};$(document).ready(function(){$("#launch_date").datetimepicker({widgetPositioning:{vertical:"bottom"},showTodayButton:!0,defaultDate:moment()}),$(".modal").on("hidden.bs.modal",function(e){$(this).removeClass("fv-modal-stack"),$("body").data("fv_open_modals",$("body").data("fv_open_modals")-1)}),$(".modal").on("shown.bs.modal",function(e){"undefined"==typeof $("body").data("fv_open_modals")&&$("body").data("fv_open_modals",0),$(this).hasClass("fv-modal-stack")||($(this).addClass("fv-modal-stack"),$("body").data("fv_open_modals",$("body").data("fv_open_modals")+1),$(this).css("z-index",1040+10*$("body").data("fv_open_modals")),$(".modal-backdrop").not(".fv-modal-stack").css("z-index",1039+10*$("body").data("fv_open_modals")),$(".modal-backdrop").not("fv-modal-stack").addClass("fv-modal-stack"))}),$(document).on("hidden.bs.modal",".modal",function(){$(".modal:visible").length&&$(document.body).addClass("modal-open")}),$("#modal").on("hidden.bs.modal",function(e){dismiss()}),api.campaigns.summary().success(function(e){campaigns=e.campaigns,$("#loading").hide(),campaigns.length>0?($("#campaignTable").show(),campaignTable=$("#campaignTable").DataTable({columnDefs:[{orderable:!1,targets:"no-sort"}],order:[[1,"desc"]]}),$.each(campaigns,function(e,a){label=labels[a.status]||"label-default",campaignTable.row.add([escapeHtml(a.name),moment(a.created_date).format("MMMM Do YYYY, h:mm:ss a"),''+a.status+"","
"]).draw(),$('[data-toggle="tooltip"]').tooltip()})):$("#emptyMessage").show()}).error(function(){$("#loading").hide(),errorFlash("Error fetching campaigns")}),$.fn.select2.defaults.set("width","100%"),$.fn.select2.defaults.set("dropdownParent",$("#modal_body")),$.fn.select2.defaults.set("theme","bootstrap")}); \ No newline at end of file +function launch(){swal({title:"Are you sure?",text:"This will schedule the campaign to be launched.",type:"question",animation:!1,showCancelButton:!0,confirmButtonText:"Launch",confirmButtonColor:"#428bca",reverseButtons:!0,allowOutsideClick:!1,showLoaderOnConfirm:!0,preConfirm:function(){return new Promise(function(a,e){groups=[],$("#users").select2("data").forEach(function(a){groups.push({name:a.text})}),campaign={name:$("#name").val(),template:{name:$("#template").select2("data")[0].text},url:$("#url").val(),page:{name:$("#page").select2("data")[0].text},smtp:{name:$("#profile").select2("data")[0].text},launch_date:moment($("#launch_date").val(),"MM/DD/YYYY hh:mm a").format(),groups:groups},api.campaigns.post(campaign).success(function(e){a(),campaign=e}).error(function(a){$("#modal\\.flashes").empty().append('
'+a.responseJSON.message+"
"),swal.close()})})}}).then(function(){swal("Campaign Scheduled!","This campaign has been scheduled for launch!","success"),$('button:contains("OK")').on("click",function(){window.location="/campaigns/"+campaign.id.toString()})})}function sendTestEmail(){var a={template:{name:$("#template").select2("data")[0].text},first_name:$("input[name=to_first_name]").val(),last_name:$("input[name=to_last_name]").val(),email:$("input[name=to_email]").val(),position:$("input[name=to_position]").val(),url:$("#url").val(),page:{name:$("#page").select2("data")[0].text},smtp:{name:$("#profile").select2("data")[0].text}};btnHtml=$("#sendTestModalSubmit").html(),$("#sendTestModalSubmit").html(' Sending'),api.send_test_email(a).success(function(a){$("#sendTestEmailModal\\.flashes").empty().append('
Email Sent!
'),$("#sendTestModalSubmit").html(btnHtml)}).error(function(a){$("#sendTestEmailModal\\.flashes").empty().append('
'+a.responseJSON.message+"
"),$("#sendTestModalSubmit").html(btnHtml)})}function dismiss(){$("#modal\\.flashes").empty(),$("#name").val(""),$("#template").val("").change(),$("#page").val("").change(),$("#url").val(""),$("#profile").val("").change(),$("#users").val("").change(),$("#modal").modal("hide")}function deleteCampaign(a){swal({title:"Are you sure?",text:"This will delete the campaign. This can't be undone!",type:"warning",animation:!1,showCancelButton:!0,confirmButtonText:"Delete "+campaigns[a].name,confirmButtonColor:"#428bca",reverseButtons:!0,allowOutsideClick:!1,preConfirm:function(){return new Promise(function(e,t){api.campaignId.delete(campaigns[a].id).success(function(a){e()}).error(function(a){t(a.responseJSON.message)})})}}).then(function(){swal("Campaign Deleted!","This campaign has been deleted!","success"),$('button:contains("OK")').on("click",function(){location.reload()})})}function setupOptions(){api.groups.get().success(function(a){if(0==a.length)return modalError("No groups found!"),!1;var e=$.map(a,function(a){return a.text=a.name,a});$("#users.form-control").select2({placeholder:"Select Groups",data:e})}),api.templates.get().success(function(a){if(0==a.length)return modalError("No templates found!"),!1;var e=$.map(a,function(a){return a.text=a.name,a});$("#template.form-control").select2({placeholder:"Select a Template",data:e})}),api.pages.get().success(function(a){if(0==a.length)return modalError("No pages found!"),!1;var e=$.map(a,function(a){return a.text=a.name,a});$("#page.form-control").select2({placeholder:"Select a Landing Page",data:e})}),api.SMTP.get().success(function(a){if(0==a.length)return modalError("No profiles found!"),!1;var e=$.map(a,function(a){return a.text=a.name,a});$("#profile.form-control").select2({placeholder:"Select a Sending Profile",data:e})})}function edit(a){setupOptions()}function copy(a){setupOptions(),api.campaignId.get(campaigns[a].id).success(function(a){$("#name").val("Copy of "+a.name),a.template.id?$("#template").select2("val",a.template.id.toString()):$("#template").select2({placeholder:a.template.name}),a.page.id?$("#page").select2("val",a.page.id.toString()):$("#page").select2({placeholder:a.page.name}),a.smtp.id?$("#profile").select2("val",a.smtp.id.toString()):$("#profile").select2({placeholder:a.smtp.name}),$("#url").val(a.url)}).error(function(a){$("#modal\\.flashes").empty().append('
'+a.responseJSON.message+"
")})}var labels={"In progress":"label-primary",Queued:"label-info",Completed:"label-success","Emails Sent":"label-success",Error:"label-danger"},campaigns=[],campaign={};$(document).ready(function(){$("#launch_date").datetimepicker({widgetPositioning:{vertical:"bottom"},showTodayButton:!0,defaultDate:moment()}),$(".modal").on("hidden.bs.modal",function(a){$(this).removeClass("fv-modal-stack"),$("body").data("fv_open_modals",$("body").data("fv_open_modals")-1)}),$(".modal").on("shown.bs.modal",function(a){"undefined"==typeof $("body").data("fv_open_modals")&&$("body").data("fv_open_modals",0),$(this).hasClass("fv-modal-stack")||($(this).addClass("fv-modal-stack"),$("body").data("fv_open_modals",$("body").data("fv_open_modals")+1),$(this).css("z-index",1040+10*$("body").data("fv_open_modals")),$(".modal-backdrop").not(".fv-modal-stack").css("z-index",1039+10*$("body").data("fv_open_modals")),$(".modal-backdrop").not("fv-modal-stack").addClass("fv-modal-stack"))}),$(document).on("hidden.bs.modal",".modal",function(){$(".modal:visible").length&&$(document.body).addClass("modal-open")}),$("#modal").on("hidden.bs.modal",function(a){dismiss()}),api.campaigns.summary().success(function(a){campaigns=a.campaigns,$("#loading").hide(),campaigns.length>0?($("#campaignTable").show(),campaignTable=$("#campaignTable").DataTable({columnDefs:[{orderable:!1,targets:"no-sort"}],order:[[1,"desc"]]}),$.each(campaigns,function(a,e){label=labels[e.status]||"label-default";var t;if(moment(e.launch_date).isAfter(moment())){t="Scheduled to start: "+moment(e.launch_date).format("MMMM Do YYYY, h:mm:ss a");var n=t+"

Number of recipients: "+e.stats.total}else{t="Launch Date: "+moment(e.launch_date).format("MMMM Do YYYY, h:mm:ss a");var n=t+"

Number of recipients: "+e.stats.total+"

Emails opened: "+e.stats.opened+"

Emails clicked: "+e.stats.clicked+"

Submitted Credentials: "+e.stats.submitted_data+"

Errors : "+e.stats.error}campaignTable.row.add([escapeHtml(e.name),moment(e.created_date).format("MMMM Do YYYY, h:mm:ss a"),''+e.status+"","
"]).draw(),$('[data-toggle="tooltip"]').tooltip()})):$("#emptyMessage").show()}).error(function(){$("#loading").hide(),errorFlash("Error fetching campaigns")}),$.fn.select2.defaults.set("width","100%"),$.fn.select2.defaults.set("dropdownParent",$("#modal_body")),$.fn.select2.defaults.set("theme","bootstrap")}); \ No newline at end of file diff --git a/static/js/dist/app/dashboard.min.js b/static/js/dist/app/dashboard.min.js index 51af68d6..59e1e6a7 100644 --- a/static/js/dist/app/dashboard.min.js +++ b/static/js/dist/app/dashboard.min.js @@ -1 +1 @@ -function deleteCampaign(a){confirm("Delete "+campaigns[a].name+"?")&&api.campaignId.delete(campaigns[a].id).success(function(a){successFlash(a.message),location.reload()})}var campaigns=[],labels={"In progress":"label-primary",Queued:"label-info",Completed:"label-success","Emails Sent":"label-success",Error:"label-danger"};$(document).ready(function(){api.campaigns.summary().success(function(a){if($("#loading").hide(),campaigns=a.campaigns,campaigns.length>0){$("#dashboard").show();var e={labels:[],series:[[]]},t={series:[]},s={axisX:{showGrid:!1},showArea:!0,plugins:[],low:0,high:100},i={donut:!0,donutWidth:40,chartPadding:0,showLabel:!1},n=0;campaignTable=$("#campaignTable").DataTable({columnDefs:[{orderable:!1,targets:"no-sort"}],order:[[1,"desc"]]}),$.each(campaigns,function(a,t){var s=moment(t.created_date).format("MMMM Do YYYY, h:mm:ss a"),i=labels[t.status]||"label-default";campaignTable.row.add([escapeHtml(t.name),s,''+t.status+"","
"]).draw(),t.y=0,t.y+=t.stats.clicked+t.stats.submitted_data,t.y=Math.floor(t.y/t.stats.total*100),n+=t.y,e.labels.push(s),e.series[0].push({meta:a,value:t.y})}),n=Math.floor(n/a.total),t.series.push({meta:"Unsuccessful Phishes",value:100-n}),t.series.push({meta:"Successful Phishes",value:n});new Chartist.Pie("#average_chart",t,i),new Chartist.Line("#overview_chart",e,s);$piechart=$("#average_chart");var c=$piechart.append('
').find(".chartist-tooltip").hide();$piechart.on("mouseenter",".ct-slice-donut",function(){var a=$(this);value=a.attr("ct:value"),label=a.attr("ct:meta"),c.html(label+": "+value.toString()+"%").show()}),$piechart.on("mouseleave",".ct-slice-donut",function(){c.hide()}),$piechart.on("mousemove",function(a){c.css({left:(a.offsetX||a.originalEvent.layerX)-c.width()/2-10,top:(a.offsetY+40||a.originalEvent.layerY)-c.height()-80})}),$chart=$("#overview_chart");var l=$chart.append('
').find(".chartist-tooltip").hide();$chart.on("mouseenter",".ct-point",function(){var a=$(this);value=a.attr("ct:value")||0,cidx=a.attr("ct:meta"),l.html(campaigns[cidx].name+"
Successes: "+value.toString()+"%").show()}),$chart.on("mouseleave",".ct-point",function(){l.hide()}),$chart.on("mousemove",function(a){l.css({left:(a.offsetX||a.originalEvent.layerX)-l.width()/2-10,top:(a.offsetY+40||a.originalEvent.layerY)-l.height()-40})}),$("#overview_chart").on("click",".ct-point",function(a){$(this).attr("ct:meta");window.location.href="/campaigns/"+campaigns[cidx].id})}else $("#emptyMessage").show()}).error(function(){errorFlash("Error fetching campaigns")})}); \ No newline at end of file +function deleteCampaign(a){confirm("Delete "+campaigns[a].name+"?")&&api.campaignId.delete(campaigns[a].id).success(function(a){successFlash(a.message),location.reload()})}var campaigns=[],labels={"In progress":"label-primary",Queued:"label-info",Completed:"label-success","Emails Sent":"label-success",Error:"label-danger"};$(document).ready(function(){api.campaigns.summary().success(function(a){if($("#loading").hide(),campaigns=a.campaigns,campaigns.length>0){$("#dashboard").show();var t={labels:[],series:[[]]},e={series:[]},s={axisX:{showGrid:!1},showArea:!0,plugins:[],low:0,high:100},i={donut:!0,donutWidth:40,chartPadding:0,showLabel:!1},o=0;campaignTable=$("#campaignTable").DataTable({columnDefs:[{orderable:!1,targets:"no-sort"}],order:[[1,"desc"]]}),$.each(campaigns,function(a,e){var s,i=moment(e.created_date).format("MMMM Do YYYY, h:mm:ss a"),r=labels[e.status]||"label-default";if(moment(e.launch_date).isAfter(moment())){s="Scheduled to start: "+moment(e.launch_date).format("MMMM Do YYYY, h:mm:ss a");var l=s+"

Number of recipients: "+e.stats.total}else{s="Launch Date: "+moment(e.launch_date).format("MMMM Do YYYY, h:mm:ss a");var l=s+"

Number of recipients: "+e.stats.total+"

Emails opened: "+e.stats.opened+"

Emails clicked: "+e.stats.clicked+"

Submitted Credentials: "+e.stats.submitted_data+"

Errors : "+e.stats.error}campaignTable.row.add([escapeHtml(e.name),i,''+e.status+"","
"]).draw(),$('[data-toggle="tooltip"]').tooltip(),e.y=0,e.y+=e.stats.clicked+e.stats.submitted_data,e.y=Math.floor(e.y/e.stats.total*100),o+=e.y,t.labels.push(i),t.series[0].push({meta:a,value:e.y})}),o=Math.floor(o/a.total),e.series.push({meta:"Unsuccessful Phishes",value:100-o}),e.series.push({meta:"Successful Phishes",value:o});new Chartist.Pie("#average_chart",e,i),new Chartist.Line("#overview_chart",t,s);$piechart=$("#average_chart");var r=$piechart.append('
').find(".chartist-tooltip").hide();$piechart.on("mouseenter",".ct-slice-donut",function(){var a=$(this);value=a.attr("ct:value"),label=a.attr("ct:meta"),r.html(label+": "+value.toString()+"%").show()}),$piechart.on("mouseleave",".ct-slice-donut",function(){r.hide()}),$piechart.on("mousemove",function(a){r.css({left:(a.offsetX||a.originalEvent.layerX)-r.width()/2-10,top:(a.offsetY+40||a.originalEvent.layerY)-r.height()-80})}),$chart=$("#overview_chart");var l=$chart.append('
').find(".chartist-tooltip").hide();$chart.on("mouseenter",".ct-point",function(){var a=$(this);value=a.attr("ct:value")||0,cidx=a.attr("ct:meta"),l.html(campaigns[cidx].name+"
Successes: "+value.toString()+"%").show()}),$chart.on("mouseleave",".ct-point",function(){l.hide()}),$chart.on("mousemove",function(a){l.css({left:(a.offsetX||a.originalEvent.layerX)-l.width()/2-10,top:(a.offsetY+40||a.originalEvent.layerY)-l.height()-40})}),$("#overview_chart").on("click",".ct-point",function(a){$(this).attr("ct:meta");window.location.href="/campaigns/"+campaigns[cidx].id})}else $("#emptyMessage").show()}).error(function(){errorFlash("Error fetching campaigns")})}); \ No newline at end of file diff --git a/static/js/src/app/campaigns.js b/static/js/src/app/campaigns.js index 78155021..f13da563 100644 --- a/static/js/src/app/campaigns.js +++ b/static/js/src/app/campaigns.js @@ -311,10 +311,21 @@ $(document).ready(function() { }); $.each(campaigns, function(i, campaign) { label = labels[campaign.status] || "label-default"; + + //section for tooltips on the status of a campaign to show some quick stats + var launchDate; + if(moment(campaign.launch_date).isAfter(moment())){ + launchDate = "Scheduled to start: "+moment(campaign.launch_date).format('MMMM Do YYYY, h:mm:ss a') + var quickStats = launchDate+"

"+"Number of recipients: "+campaign.stats.total + } else { + launchDate = "Launch Date: "+moment(campaign.launch_date).format('MMMM Do YYYY, h:mm:ss a') + var quickStats = launchDate+"

"+"Number of recipients: "+campaign.stats.total+"

"+"Emails opened: "+campaign.stats.opened+"

"+"Emails clicked: "+campaign.stats.clicked+"

"+"Submitted Credentials: "+campaign.stats.submitted_data+"

"+"Errors : "+campaign.stats.error + } + campaignTable.row.add([ escapeHtml(campaign.name), moment(campaign.created_date).format('MMMM Do YYYY, h:mm:ss a'), - "" + campaign.status + "", + "" + campaign.status + "", "
\ \ \ diff --git a/static/js/src/app/dashboard.js b/static/js/src/app/dashboard.js index 6bfd8acb..9b3e0efb 100644 --- a/static/js/src/app/dashboard.js +++ b/static/js/src/app/dashboard.js @@ -64,18 +64,28 @@ $(document).ready(function() { $.each(campaigns, function(i, campaign) { var campaign_date = moment(campaign.created_date).format('MMMM Do YYYY, h:mm:ss a') var label = labels[campaign.status] || "label-default"; + //section for tooltips on the status of a campaign to show some quick stats + var launchDate; + if (moment(campaign.launch_date).isAfter(moment())) { + launchDate = "Scheduled to start: " + moment(campaign.launch_date).format('MMMM Do YYYY, h:mm:ss a') + var quickStats = launchDate + "

" + "Number of recipients: " + campaign.stats.total + } else { + launchDate = "Launch Date: " + moment(campaign.launch_date).format('MMMM Do YYYY, h:mm:ss a') + var quickStats = launchDate + "

" + "Number of recipients: " + campaign.stats.total + "

" + "Emails opened: " + campaign.stats.opened + "

" + "Emails clicked: " + campaign.stats.clicked + "

" + "Submitted Credentials: " + campaign.stats.submitted_data + "

" + "Errors : " + campaign.stats.error + } // Add it to the table campaignTable.row.add([ escapeHtml(campaign.name), campaign_date, - "" + campaign.status + "", - "
\ + "" + campaign.status + "", + "
\ \ \ -
" ]).draw() + $('[data-toggle="tooltip"]').tooltip() // Add it to the chart data campaign.y = 0 campaign.y += campaign.stats.clicked + campaign.stats.submitted_data