mirror of https://github.com/gophish/gophish
Formatting Javascript using js-beautifier
parent
e78ec27ef2
commit
2dda83814c
|
@ -2,254 +2,267 @@ var map = null
|
|||
|
||||
// statuses is a helper map to point result statuses to ui classes
|
||||
var statuses = {
|
||||
"Email Sent" : {
|
||||
"Email Sent": {
|
||||
slice: "ct-slice-donut-sent",
|
||||
legend: "ct-legend-sent",
|
||||
label: "label-success"
|
||||
},
|
||||
"Email Opened" : {
|
||||
"Email Opened": {
|
||||
slice: "ct-slice-donut-opened",
|
||||
legend: "ct-legend-opened",
|
||||
label: "label-warning"
|
||||
},
|
||||
"Clicked Link" : {
|
||||
"Clicked Link": {
|
||||
slice: "ct-slice-donut-clicked",
|
||||
legend: "ct-legend-clicked",
|
||||
label: "label-danger"
|
||||
},
|
||||
"Success" : {
|
||||
"Success": {
|
||||
slice: "ct-slice-donut-clicked",
|
||||
legend: "ct-legend-clicked",
|
||||
label: "label-danger"
|
||||
},
|
||||
"Error" : {
|
||||
"Error": {
|
||||
slice: "ct-slice-donut-error",
|
||||
legend: "ct-legend-error",
|
||||
label: "label-default"
|
||||
},
|
||||
"Unknown" : {
|
||||
slice: "ct-slice-donut-error",
|
||||
legend: "ct-legend-error",
|
||||
label: "label-default"
|
||||
"Unknown": {
|
||||
slice: "ct-slice-donut-error",
|
||||
legend: "ct-legend-error",
|
||||
label: "label-default"
|
||||
}
|
||||
}
|
||||
|
||||
var campaign = {}
|
||||
|
||||
function dismiss(){
|
||||
function dismiss() {
|
||||
$("#modal\\.flashes").empty()
|
||||
$("#modal").modal('hide')
|
||||
$("#resultsTable").dataTable().DataTable().clear().draw()
|
||||
}
|
||||
|
||||
// Deletes a campaign after prompting the user
|
||||
function deleteCampaign(){
|
||||
if (confirm("Are you sure you want to delete: " + campaign.name + "?")){
|
||||
function deleteCampaign() {
|
||||
if (confirm("Are you sure you want to delete: " + campaign.name + "?")) {
|
||||
api.campaignId.delete(campaign.id)
|
||||
.success(function(msg){
|
||||
console.log(msg)
|
||||
})
|
||||
.error(function(e){
|
||||
$("#modal\\.flashes").empty().append("<div style=\"text-align:center\" class=\"alert alert-danger\">\
|
||||
.success(function(msg) {
|
||||
console.log(msg)
|
||||
})
|
||||
.error(function(e) {
|
||||
$("#modal\\.flashes").empty().append("<div style=\"text-align:center\" class=\"alert alert-danger\">\
|
||||
<i class=\"fa fa-exclamation-circle\"></i> " + data.responseJSON.message + "</div>")
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$(document).ready(function() {
|
||||
campaign.id = window.location.pathname.split('/').slice(-1)[0]
|
||||
api.campaignId.get(campaign.id)
|
||||
.success(function(c){
|
||||
campaign = c
|
||||
if (campaign){
|
||||
// Set the title
|
||||
$("#page-title").text("Results for " + c.name)
|
||||
// Setup tooltips
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
// Setup our graphs
|
||||
var timeline_data = {series:[{
|
||||
name: "Events",
|
||||
data: []
|
||||
}]}
|
||||
var email_data = {series:[]}
|
||||
var email_legend = {}
|
||||
var email_series_data = {}
|
||||
var timeline_opts = {
|
||||
axisX: {
|
||||
showGrid: false,
|
||||
type: Chartist.FixedScaleAxis,
|
||||
divisor: 5,
|
||||
labelInterpolationFnc: function(value){
|
||||
return moment(value).format('MMMM Do YYYY h:mm')
|
||||
}
|
||||
},
|
||||
axisY: {
|
||||
type: Chartist.FixedScaleAxis,
|
||||
ticks: [0, 1, 2],
|
||||
low: 0,
|
||||
showLabel: false
|
||||
},
|
||||
showArea: false,
|
||||
plugins: []
|
||||
}
|
||||
var email_opts = {
|
||||
donut : true,
|
||||
donutWidth: 40,
|
||||
chartPadding: 0,
|
||||
showLabel: false
|
||||
}
|
||||
// Setup the results table
|
||||
resultsTable = $("#resultsTable").DataTable();
|
||||
$.each(campaign.results, function(i, result){
|
||||
label = statuses[result.status].label || "label-default";
|
||||
resultsTable.row.add([
|
||||
result.first_name || "",
|
||||
result.last_name || "",
|
||||
result.email || "",
|
||||
result.position || "",
|
||||
"<span class=\"label " + label + "\">" + result.status + "</span>"
|
||||
]).draw()
|
||||
if (!email_series_data[result.status]){
|
||||
email_series_data[result.status] = 1
|
||||
} else {
|
||||
email_series_data[result.status]++;
|
||||
.success(function(c) {
|
||||
campaign = c
|
||||
if (campaign) {
|
||||
// Set the title
|
||||
$("#page-title").text("Results for " + c.name)
|
||||
// Setup tooltips
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
// Setup our graphs
|
||||
var timeline_data = {
|
||||
series: [{
|
||||
name: "Events",
|
||||
data: []
|
||||
}]
|
||||
}
|
||||
})
|
||||
// Setup the graphs
|
||||
$.each(campaign.timeline, function(i, event){
|
||||
timeline_data.series[0].data.push({meta : i, x: new Date(event.time), y:1})
|
||||
})
|
||||
$.each(email_series_data, function(status, count){
|
||||
email_data.series.push({meta: status, value: count})
|
||||
})
|
||||
var timeline_chart = new Chartist.Line('#timeline_chart', timeline_data, timeline_opts)
|
||||
// Setup the overview chart listeners
|
||||
$chart = $("#timeline_chart")
|
||||
var $toolTip = $chart
|
||||
.append('<div class="chartist-tooltip"></div>')
|
||||
.find('.chartist-tooltip')
|
||||
.hide();
|
||||
$chart.on('mouseenter', '.ct-point', function() {
|
||||
var $point = $(this)
|
||||
value = $point.attr('ct:value')
|
||||
cidx = $point.attr('ct:meta')
|
||||
html = "Event: " + campaign.timeline[cidx].message
|
||||
if (campaign.timeline[cidx].email) {
|
||||
html += '<br>' + "Email: " + campaign.timeline[cidx].email
|
||||
var email_data = {
|
||||
series: []
|
||||
}
|
||||
$toolTip.html(html).show()
|
||||
});
|
||||
$chart.on('mouseleave', '.ct-point', function() {
|
||||
$toolTip.hide();
|
||||
});
|
||||
$chart.on('mousemove', function(event) {
|
||||
$toolTip.css({
|
||||
left: (event.offsetX || event.originalEvent.layerX) - $toolTip.width() / 2 - 10,
|
||||
top: (event.offsetY + 70 || event.originalEvent.layerY) - $toolTip.height() - 40
|
||||
});
|
||||
});
|
||||
var email_chart = new Chartist.Pie("#email_chart", email_data, email_opts)
|
||||
email_chart.on('draw', function(data){
|
||||
// We don't want to create the legend twice
|
||||
if (!email_legend[data.meta]) {
|
||||
console.log(data.meta)
|
||||
$("#email_chart_legend").append('<li><span class="' + statuses[data.meta].legend + '"></span>' + data.meta + '</li>')
|
||||
email_legend[data.meta] = true
|
||||
}
|
||||
data.element.addClass(statuses[data.meta].slice)
|
||||
})
|
||||
// Setup the average chart listeners
|
||||
$piechart = $("#email_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
|
||||
});
|
||||
});
|
||||
$("#loading").hide()
|
||||
$("#campaignResults").show()
|
||||
map = new Datamap({
|
||||
element: document.getElementById("resultsMap"),
|
||||
responsive: true,
|
||||
fills: {
|
||||
defaultFill: "#ffffff",
|
||||
point: "#283F50"
|
||||
},
|
||||
geographyConfig: {
|
||||
highlightFillColor : "#1abc9c",
|
||||
borderColor:"#283F50"
|
||||
},
|
||||
bubblesConfig: {
|
||||
borderColor: "#283F50"
|
||||
}
|
||||
});
|
||||
bubbles = []
|
||||
$.each(campaign.results, function(i, result){
|
||||
// Check that it wasn't an internal IP
|
||||
if (result.latitude == 0 && result.longitude == 0) { return true; }
|
||||
newIP = true
|
||||
$.each(bubbles, function(i, bubble){
|
||||
if (bubble.ip == result.ip){
|
||||
bubbles[i].radius += 1
|
||||
newIP = false
|
||||
return false
|
||||
}
|
||||
})
|
||||
if (newIP){
|
||||
console.log("Adding bubble at: ")
|
||||
console.log({
|
||||
latitude : result.latitude,
|
||||
longitude: result.longitude,
|
||||
name : result.ip,
|
||||
fillKey: "point"
|
||||
})
|
||||
bubbles.push({
|
||||
latitude : result.latitude,
|
||||
longitude: result.longitude,
|
||||
name : result.ip,
|
||||
fillKey: "point",
|
||||
radius: 2
|
||||
})
|
||||
}
|
||||
})
|
||||
map.bubbles(bubbles)
|
||||
}
|
||||
// Load up the map data (only once!)
|
||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||
if ($(e.target).attr('href') == "#overview"){
|
||||
if (!map){
|
||||
map = new Datamap({
|
||||
element: document.getElementById("resultsMap"),
|
||||
responsive: true,
|
||||
fills: {
|
||||
defaultFill: "#ffffff"
|
||||
},
|
||||
geographyConfig: {
|
||||
highlightFillColor : "#1abc9c",
|
||||
borderColor:"#283F50"
|
||||
var email_legend = {}
|
||||
var email_series_data = {}
|
||||
var timeline_opts = {
|
||||
axisX: {
|
||||
showGrid: false,
|
||||
type: Chartist.FixedScaleAxis,
|
||||
divisor: 5,
|
||||
labelInterpolationFnc: function(value) {
|
||||
return moment(value).format('MMMM Do YYYY h:mm')
|
||||
}
|
||||
});
|
||||
},
|
||||
axisY: {
|
||||
type: Chartist.FixedScaleAxis,
|
||||
ticks: [0, 1, 2],
|
||||
low: 0,
|
||||
showLabel: false
|
||||
},
|
||||
showArea: false,
|
||||
plugins: []
|
||||
}
|
||||
var email_opts = {
|
||||
donut: true,
|
||||
donutWidth: 40,
|
||||
chartPadding: 0,
|
||||
showLabel: false
|
||||
}
|
||||
// Setup the results table
|
||||
resultsTable = $("#resultsTable").DataTable();
|
||||
$.each(campaign.results, function(i, result) {
|
||||
label = statuses[result.status].label || "label-default";
|
||||
resultsTable.row.add([
|
||||
result.first_name || "",
|
||||
result.last_name || "",
|
||||
result.email || "",
|
||||
result.position || "",
|
||||
"<span class=\"label " + label + "\">" + result.status + "</span>"
|
||||
]).draw()
|
||||
if (!email_series_data[result.status]) {
|
||||
email_series_data[result.status] = 1
|
||||
} else {
|
||||
email_series_data[result.status]++;
|
||||
}
|
||||
})
|
||||
// Setup the graphs
|
||||
$.each(campaign.timeline, function(i, event) {
|
||||
timeline_data.series[0].data.push({
|
||||
meta: i,
|
||||
x: new Date(event.time),
|
||||
y: 1
|
||||
})
|
||||
})
|
||||
$.each(email_series_data, function(status, count) {
|
||||
email_data.series.push({
|
||||
meta: status,
|
||||
value: count
|
||||
})
|
||||
})
|
||||
var timeline_chart = new Chartist.Line('#timeline_chart', timeline_data, timeline_opts)
|
||||
// Setup the overview chart listeners
|
||||
$chart = $("#timeline_chart")
|
||||
var $toolTip = $chart
|
||||
.append('<div class="chartist-tooltip"></div>')
|
||||
.find('.chartist-tooltip')
|
||||
.hide();
|
||||
$chart.on('mouseenter', '.ct-point', function() {
|
||||
var $point = $(this)
|
||||
value = $point.attr('ct:value')
|
||||
cidx = $point.attr('ct:meta')
|
||||
html = "Event: " + campaign.timeline[cidx].message
|
||||
if (campaign.timeline[cidx].email) {
|
||||
html += '<br>' + "Email: " + campaign.timeline[cidx].email
|
||||
}
|
||||
$toolTip.html(html).show()
|
||||
});
|
||||
$chart.on('mouseleave', '.ct-point', function() {
|
||||
$toolTip.hide();
|
||||
});
|
||||
$chart.on('mousemove', function(event) {
|
||||
$toolTip.css({
|
||||
left: (event.offsetX || event.originalEvent.layerX) - $toolTip.width() / 2 - 10,
|
||||
top: (event.offsetY + 70 || event.originalEvent.layerY) - $toolTip.height() - 40
|
||||
});
|
||||
});
|
||||
var email_chart = new Chartist.Pie("#email_chart", email_data, email_opts)
|
||||
email_chart.on('draw', function(data) {
|
||||
// We don't want to create the legend twice
|
||||
if (!email_legend[data.meta]) {
|
||||
console.log(data.meta)
|
||||
$("#email_chart_legend").append('<li><span class="' + statuses[data.meta].legend + '"></span>' + data.meta + '</li>')
|
||||
email_legend[data.meta] = true
|
||||
}
|
||||
data.element.addClass(statuses[data.meta].slice)
|
||||
})
|
||||
// Setup the average chart listeners
|
||||
$piechart = $("#email_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
|
||||
});
|
||||
});
|
||||
$("#loading").hide()
|
||||
$("#campaignResults").show()
|
||||
map = new Datamap({
|
||||
element: document.getElementById("resultsMap"),
|
||||
responsive: true,
|
||||
fills: {
|
||||
defaultFill: "#ffffff",
|
||||
point: "#283F50"
|
||||
},
|
||||
geographyConfig: {
|
||||
highlightFillColor: "#1abc9c",
|
||||
borderColor: "#283F50"
|
||||
},
|
||||
bubblesConfig: {
|
||||
borderColor: "#283F50"
|
||||
}
|
||||
});
|
||||
bubbles = []
|
||||
$.each(campaign.results, function(i, result) {
|
||||
// Check that it wasn't an internal IP
|
||||
if (result.latitude == 0 && result.longitude == 0) {
|
||||
return true;
|
||||
}
|
||||
newIP = true
|
||||
$.each(bubbles, function(i, bubble) {
|
||||
if (bubble.ip == result.ip) {
|
||||
bubbles[i].radius += 1
|
||||
newIP = false
|
||||
return false
|
||||
}
|
||||
})
|
||||
if (newIP) {
|
||||
console.log("Adding bubble at: ")
|
||||
console.log({
|
||||
latitude: result.latitude,
|
||||
longitude: result.longitude,
|
||||
name: result.ip,
|
||||
fillKey: "point"
|
||||
})
|
||||
bubbles.push({
|
||||
latitude: result.latitude,
|
||||
longitude: result.longitude,
|
||||
name: result.ip,
|
||||
fillKey: "point",
|
||||
radius: 2
|
||||
})
|
||||
}
|
||||
})
|
||||
map.bubbles(bubbles)
|
||||
}
|
||||
// Load up the map data (only once!)
|
||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
|
||||
if ($(e.target).attr('href') == "#overview") {
|
||||
if (!map) {
|
||||
map = new Datamap({
|
||||
element: document.getElementById("resultsMap"),
|
||||
responsive: true,
|
||||
fills: {
|
||||
defaultFill: "#ffffff"
|
||||
},
|
||||
geographyConfig: {
|
||||
highlightFillColor: "#1abc9c",
|
||||
borderColor: "#283F50"
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
.error(function() {
|
||||
$("#loading").hide()
|
||||
errorFlash(" Campaign not found!")
|
||||
})
|
||||
})
|
||||
.error(function(){
|
||||
$("#loading").hide()
|
||||
errorFlash(" Campaign not found!")
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,212 +1,226 @@
|
|||
// labels is a map of campaign statuses to
|
||||
// CSS classes
|
||||
var labels = {
|
||||
"In progress" : "label-primary",
|
||||
"Queued" : "label-info",
|
||||
"Completed" : "label-success",
|
||||
"Emails Sent" : "label-success",
|
||||
"Error" : "label-danger"
|
||||
"In progress": "label-primary",
|
||||
"Queued": "label-info",
|
||||
"Completed": "label-success",
|
||||
"Emails Sent": "label-success",
|
||||
"Error": "label-danger"
|
||||
}
|
||||
|
||||
// Save attempts to POST to /campaigns/
|
||||
function save(){
|
||||
function save() {
|
||||
groups = []
|
||||
$.each($("#groupTable").DataTable().rows().data(), function(i, group){
|
||||
groups.push({name: group[0]})
|
||||
$.each($("#groupTable").DataTable().rows().data(), function(i, group) {
|
||||
groups.push({
|
||||
name: group[0]
|
||||
})
|
||||
})
|
||||
console.log(groups)
|
||||
var campaign = {
|
||||
name: $("#name").val(),
|
||||
template:{
|
||||
name: $("#template").val()
|
||||
},
|
||||
url: $("#url").val(),
|
||||
page: {
|
||||
name: $("#page").val()
|
||||
},
|
||||
smtp: {
|
||||
from_address: $("input[name=from]").val(),
|
||||
host: $("input[name=host]").val(),
|
||||
username: $("input[name=username]").val(),
|
||||
password: $("input[name=password]").val(),
|
||||
},
|
||||
groups: groups
|
||||
}
|
||||
// Submit the campaign
|
||||
name: $("#name").val(),
|
||||
template: {
|
||||
name: $("#template").val()
|
||||
},
|
||||
url: $("#url").val(),
|
||||
page: {
|
||||
name: $("#page").val()
|
||||
},
|
||||
smtp: {
|
||||
from_address: $("input[name=from]").val(),
|
||||
host: $("input[name=host]").val(),
|
||||
username: $("input[name=username]").val(),
|
||||
password: $("input[name=password]").val(),
|
||||
},
|
||||
groups: groups
|
||||
}
|
||||
// Submit the campaign
|
||||
api.campaigns.post(campaign)
|
||||
.success(function(data){
|
||||
successFlash("Campaign successfully launched!")
|
||||
window.location = "/campaigns/" + campaign.id.toString()
|
||||
})
|
||||
.error(function(data){
|
||||
$("#modal\\.flashes").empty().append("<div style=\"text-align:center\" class=\"alert alert-danger\">\
|
||||
.success(function(data) {
|
||||
successFlash("Campaign successfully launched!")
|
||||
window.location = "/campaigns/" + campaign.id.toString()
|
||||
})
|
||||
.error(function(data) {
|
||||
$("#modal\\.flashes").empty().append("<div style=\"text-align:center\" class=\"alert alert-danger\">\
|
||||
<i class=\"fa fa-exclamation-circle\"></i> " + data.responseJSON.message + "</div>")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function dismiss(){
|
||||
function dismiss() {
|
||||
$("#modal\\.flashes").empty()
|
||||
$("#modal").modal('hide')
|
||||
$("#groupTable").dataTable().DataTable().clear().draw()
|
||||
}
|
||||
|
||||
function edit(campaign){
|
||||
function edit(campaign) {
|
||||
// Clear the bloodhound instance
|
||||
group_bh.clear();
|
||||
template_bh.clear();
|
||||
page_bh.clear();
|
||||
if (campaign == "new") {
|
||||
api.groups.get()
|
||||
.success(function(groups){
|
||||
if (groups.length == 0){
|
||||
modalError("No groups found!")
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
group_bh.add(groups)
|
||||
}
|
||||
})
|
||||
api.templates.get()
|
||||
.success(function(templates){
|
||||
if (templates.length == 0){
|
||||
modalError("No templates found!")
|
||||
return false
|
||||
}
|
||||
else {
|
||||
template_bh.add(templates)
|
||||
}
|
||||
})
|
||||
api.pages.get()
|
||||
.success(function(pages){
|
||||
if (pages.length == 0){
|
||||
modalError("No pages found!")
|
||||
return false
|
||||
}
|
||||
else {
|
||||
page_bh.add(pages)
|
||||
}
|
||||
})
|
||||
.success(function(groups) {
|
||||
if (groups.length == 0) {
|
||||
modalError("No groups found!")
|
||||
return false;
|
||||
} else {
|
||||
group_bh.add(groups)
|
||||
}
|
||||
})
|
||||
api.templates.get()
|
||||
.success(function(templates) {
|
||||
if (templates.length == 0) {
|
||||
modalError("No templates found!")
|
||||
return false
|
||||
} else {
|
||||
template_bh.add(templates)
|
||||
}
|
||||
})
|
||||
api.pages.get()
|
||||
.success(function(pages) {
|
||||
if (pages.length == 0) {
|
||||
modalError("No pages found!")
|
||||
return false
|
||||
} else {
|
||||
page_bh.add(pages)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$(document).ready(function() {
|
||||
api.campaigns.get()
|
||||
.success(function(campaigns){
|
||||
$("#loading").hide()
|
||||
if (campaigns.length > 0){
|
||||
$("#campaignTable").show()
|
||||
campaignTable = $("#campaignTable").DataTable();
|
||||
$.each(campaigns, function(i, campaign){
|
||||
label = labels[campaign.status] || "label-default";
|
||||
campaignTable.row.add([
|
||||
campaign.name,
|
||||
moment(campaign.created_date).format('MMMM Do YYYY, h:mm:ss a'),
|
||||
"<span class=\"label " + label + "\">" + campaign.status + "</span>",
|
||||
"<div class='pull-right'><a class='btn btn-primary' href='/campaigns/" + campaign.id + "'>\
|
||||
.success(function(campaigns) {
|
||||
$("#loading").hide()
|
||||
if (campaigns.length > 0) {
|
||||
$("#campaignTable").show()
|
||||
campaignTable = $("#campaignTable").DataTable();
|
||||
$.each(campaigns, function(i, campaign) {
|
||||
label = labels[campaign.status] || "label-default";
|
||||
campaignTable.row.add([
|
||||
campaign.name,
|
||||
moment(campaign.created_date).format('MMMM Do YYYY, h:mm:ss a'),
|
||||
"<span class=\"label " + label + "\">" + campaign.status + "</span>",
|
||||
"<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='alert(\"test\")'>\
|
||||
<i class='fa fa-trash-o'></i>\
|
||||
</button></div>"
|
||||
]).draw()
|
||||
})
|
||||
} else {
|
||||
$("#emptyMessage").show()
|
||||
}
|
||||
})
|
||||
.error(function(){
|
||||
$("#loading").hide()
|
||||
errorFlash("Error fetching campaigns")
|
||||
})
|
||||
$("#groupForm").submit(function(){
|
||||
groupTable.row.add([
|
||||
$("#groupSelect").val(),
|
||||
'<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>'
|
||||
]).draw()
|
||||
$("#groupTable").on("click", "span>i.fa-trash-o", function(){
|
||||
groupTable.row( $(this).parents('tr') )
|
||||
.remove()
|
||||
.draw();
|
||||
]).draw()
|
||||
})
|
||||
} else {
|
||||
$("#emptyMessage").show()
|
||||
}
|
||||
})
|
||||
return false;
|
||||
})
|
||||
// Create the group typeahead objects
|
||||
.error(function() {
|
||||
$("#loading").hide()
|
||||
errorFlash("Error fetching campaigns")
|
||||
})
|
||||
$("#groupForm").submit(function() {
|
||||
groupTable.row.add([
|
||||
$("#groupSelect").val(),
|
||||
'<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>'
|
||||
]).draw()
|
||||
$("#groupTable").on("click", "span>i.fa-trash-o", function() {
|
||||
groupTable.row($(this).parents('tr'))
|
||||
.remove()
|
||||
.draw();
|
||||
})
|
||||
return false;
|
||||
})
|
||||
// Create the group typeahead objects
|
||||
groupTable = $("#groupTable").DataTable()
|
||||
group_bh = new Bloodhound({
|
||||
datumTokenizer: function(g) { return Bloodhound.tokenizers.whitespace(g.name) },
|
||||
datumTokenizer: function(g) {
|
||||
return Bloodhound.tokenizers.whitespace(g.name)
|
||||
},
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
local: []
|
||||
})
|
||||
group_bh.initialize()
|
||||
$("#groupSelect.typeahead.form-control").typeahead({
|
||||
hint: true,
|
||||
highlight: true,
|
||||
minLength: 1
|
||||
},
|
||||
{
|
||||
name: "groups",
|
||||
source: group_bh,
|
||||
templates: {
|
||||
empty: function(data) {return '<div class="tt-suggestion">No groups matched that query</div>' },
|
||||
suggestion: function(data){ return '<div>' + data.name + '</div>' }
|
||||
}
|
||||
})
|
||||
.bind('typeahead:select', function(ev, group){
|
||||
$("#groupSelect").typeahead('val', group.name)
|
||||
})
|
||||
.bind('typeahead:autocomplete', function(ev, group){
|
||||
$("#groupSelect").typeahead('val', group.name)
|
||||
});
|
||||
hint: true,
|
||||
highlight: true,
|
||||
minLength: 1
|
||||
}, {
|
||||
name: "groups",
|
||||
source: group_bh,
|
||||
templates: {
|
||||
empty: function(data) {
|
||||
return '<div class="tt-suggestion">No groups matched that query</div>'
|
||||
},
|
||||
suggestion: function(data) {
|
||||
return '<div>' + data.name + '</div>'
|
||||
}
|
||||
}
|
||||
})
|
||||
.bind('typeahead:select', function(ev, group) {
|
||||
$("#groupSelect").typeahead('val', group.name)
|
||||
})
|
||||
.bind('typeahead:autocomplete', function(ev, group) {
|
||||
$("#groupSelect").typeahead('val', group.name)
|
||||
});
|
||||
// Create the template typeahead objects
|
||||
template_bh = new Bloodhound({
|
||||
datumTokenizer: function(t) { return Bloodhound.tokenizers.whitespace(t.name) },
|
||||
datumTokenizer: function(t) {
|
||||
return Bloodhound.tokenizers.whitespace(t.name)
|
||||
},
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
local: []
|
||||
})
|
||||
template_bh.initialize()
|
||||
$("#template.typeahead.form-control").typeahead({
|
||||
hint: true,
|
||||
highlight: true,
|
||||
minLength: 1
|
||||
},
|
||||
{
|
||||
name: "templates",
|
||||
source: template_bh,
|
||||
templates: {
|
||||
empty: function(data) {return '<div class="tt-suggestion">No templates matched that query</div>' },
|
||||
suggestion: function(data){ return '<div>' + data.name + '</div>' }
|
||||
}
|
||||
})
|
||||
.bind('typeahead:select', function(ev, template){
|
||||
$("#template").typeahead('val', template.name)
|
||||
})
|
||||
.bind('typeahead:autocomplete', function(ev, template){
|
||||
$("#template").typeahead('val', template.name)
|
||||
});
|
||||
hint: true,
|
||||
highlight: true,
|
||||
minLength: 1
|
||||
}, {
|
||||
name: "templates",
|
||||
source: template_bh,
|
||||
templates: {
|
||||
empty: function(data) {
|
||||
return '<div class="tt-suggestion">No templates matched that query</div>'
|
||||
},
|
||||
suggestion: function(data) {
|
||||
return '<div>' + data.name + '</div>'
|
||||
}
|
||||
}
|
||||
})
|
||||
.bind('typeahead:select', function(ev, template) {
|
||||
$("#template").typeahead('val', template.name)
|
||||
})
|
||||
.bind('typeahead:autocomplete', function(ev, template) {
|
||||
$("#template").typeahead('val', template.name)
|
||||
});
|
||||
// Create the landing page typeahead objects
|
||||
page_bh = new Bloodhound({
|
||||
datumTokenizer: function(p) { return Bloodhound.tokenizers.whitespace(p.name) },
|
||||
datumTokenizer: function(p) {
|
||||
return Bloodhound.tokenizers.whitespace(p.name)
|
||||
},
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
local: []
|
||||
})
|
||||
page_bh.initialize()
|
||||
$("#page.typeahead.form-control").typeahead({
|
||||
hint: true,
|
||||
highlight: true,
|
||||
minLength: 1
|
||||
},
|
||||
{
|
||||
name: "pages",
|
||||
source: page_bh,
|
||||
templates: {
|
||||
empty: function(data) {return '<div class="tt-suggestion">No pages matched that query</div>' },
|
||||
suggestion: function(data){ return '<div>' + data.name + '</div>' }
|
||||
}
|
||||
})
|
||||
.bind('typeahead:select', function(ev, page){
|
||||
$("#page").typeahead('val', page.name)
|
||||
})
|
||||
.bind('typeahead:autocomplete', function(ev, page){
|
||||
$("#page").typeahead('val', page.name)
|
||||
});
|
||||
hint: true,
|
||||
highlight: true,
|
||||
minLength: 1
|
||||
}, {
|
||||
name: "pages",
|
||||
source: page_bh,
|
||||
templates: {
|
||||
empty: function(data) {
|
||||
return '<div class="tt-suggestion">No pages matched that query</div>'
|
||||
},
|
||||
suggestion: function(data) {
|
||||
return '<div>' + data.name + '</div>'
|
||||
}
|
||||
}
|
||||
})
|
||||
.bind('typeahead:select', function(ev, page) {
|
||||
$("#page").typeahead('val', page.name)
|
||||
})
|
||||
.bind('typeahead:autocomplete', function(ev, page) {
|
||||
$("#page").typeahead('val', page.name)
|
||||
});
|
||||
})
|
||||
|
|
|
@ -1,129 +1,145 @@
|
|||
var campaigns = []
|
||||
// labels is a map of campaign statuses to
|
||||
// CSS classes
|
||||
// labels is a map of campaign statuses to
|
||||
// CSS classes
|
||||
var labels = {
|
||||
"In progress" : "label-primary",
|
||||
"Queued" : "label-info",
|
||||
"Completed" : "label-success",
|
||||
"Emails Sent" : "label-success",
|
||||
"Error" : "label-danger"
|
||||
"In progress": "label-primary",
|
||||
"Queued": "label-info",
|
||||
"Completed": "label-success",
|
||||
"Emails Sent": "label-success",
|
||||
"Error": "label-danger"
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$(document).ready(function() {
|
||||
api.campaigns.get()
|
||||
.success(function(cs){
|
||||
$("#loading").hide()
|
||||
campaigns = cs
|
||||
if (campaigns.length > 0){
|
||||
$("#dashboard").show()
|
||||
// Create the overview chart data
|
||||
var overview_data = {labels:[],series:[[]]}
|
||||
var average_data = {series:[]}
|
||||
var overview_opts = {
|
||||
axisX: {
|
||||
showGrid: false
|
||||
},
|
||||
showArea: true,
|
||||
plugins: []
|
||||
}
|
||||
var average_opts = {
|
||||
donut : true,
|
||||
donutWidth: 40,
|
||||
chartPadding: 0,
|
||||
showLabel: false
|
||||
}
|
||||
var average = 0
|
||||
campaignTable = $("#campaignTable").DataTable();
|
||||
$.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";
|
||||
// Add it to the table
|
||||
campaignTable.row.add([
|
||||
campaign.name,
|
||||
campaign_date,
|
||||
"<span class=\"label " + label + "\">" + campaign.status + "</span>",
|
||||
"<div class='pull-right'><a class='btn btn-primary' href='/campaigns/" + campaign.id + "'>\
|
||||
.success(function(cs) {
|
||||
$("#loading").hide()
|
||||
campaigns = cs
|
||||
if (campaigns.length > 0) {
|
||||
$("#dashboard").show()
|
||||
// Create the overview chart data
|
||||
var overview_data = {
|
||||
labels: [],
|
||||
series: [
|
||||
[]
|
||||
]
|
||||
}
|
||||
var average_data = {
|
||||
series: []
|
||||
}
|
||||
var overview_opts = {
|
||||
axisX: {
|
||||
showGrid: false
|
||||
},
|
||||
showArea: true,
|
||||
plugins: []
|
||||
}
|
||||
var average_opts = {
|
||||
donut: true,
|
||||
donutWidth: 40,
|
||||
chartPadding: 0,
|
||||
showLabel: false
|
||||
}
|
||||
var average = 0
|
||||
campaignTable = $("#campaignTable").DataTable();
|
||||
$.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";
|
||||
// Add it to the table
|
||||
campaignTable.row.add([
|
||||
campaign.name,
|
||||
campaign_date,
|
||||
"<span class=\"label " + label + "\">" + campaign.status + "</span>",
|
||||
"<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()
|
||||
// Add it to the chart data
|
||||
campaign.y = 0
|
||||
$.each(campaign.results, function(j, result){
|
||||
if (result.status == "Success"){
|
||||
campaign.y++;
|
||||
}
|
||||
]).draw()
|
||||
// Add it to the chart data
|
||||
campaign.y = 0
|
||||
$.each(campaign.results, function(j, result) {
|
||||
if (result.status == "Success") {
|
||||
campaign.y++;
|
||||
}
|
||||
})
|
||||
campaign.y = Math.floor((campaign.y / campaign.results.length) * 100)
|
||||
average += campaign.y
|
||||
// Add the data to the overview chart
|
||||
overview_data.labels.push(campaign_date)
|
||||
overview_data.series[0].push({
|
||||
meta: i,
|
||||
value: campaign.y
|
||||
})
|
||||
})
|
||||
campaign.y = Math.floor((campaign.y / campaign.results.length) * 100)
|
||||
average += campaign.y
|
||||
// Add the data to the overview chart
|
||||
overview_data.labels.push(campaign_date)
|
||||
overview_data.series[0].push({meta : i, value: campaign.y})
|
||||
})
|
||||
average = Math.floor(average / campaigns.length);
|
||||
average_data.series.push({meta: "Unsuccessful Phishes", value: 100 - average})
|
||||
average_data.series.push({meta: "Successful Phishes", value: average})
|
||||
// Build the charts
|
||||
var average_chart = new Chartist.Pie("#average_chart", average_data, average_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();
|
||||
average = Math.floor(average / campaigns.length);
|
||||
average_data.series.push({
|
||||
meta: "Unsuccessful Phishes",
|
||||
value: 100 - average
|
||||
})
|
||||
average_data.series.push({
|
||||
meta: "Successful Phishes",
|
||||
value: average
|
||||
})
|
||||
// Build the charts
|
||||
var average_chart = new Chartist.Pie("#average_chart", average_data, average_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
|
||||
$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();
|
||||
});
|
||||
});
|
||||
|
||||
// Setup the overview chart listeners
|
||||
$chart = $("#overview_chart")
|
||||
var $toolTip = $chart
|
||||
.append('<div class="chartist-tooltip"></div>')
|
||||
.find('.chartist-tooltip')
|
||||
.hide();
|
||||
|
||||
$chart.on('mouseenter', '.ct-point', function() {
|
||||
var $point = $(this)
|
||||
value = $point.attr('ct:value') || 0
|
||||
cidx = $point.attr('ct:meta')
|
||||
$toolTip.html(campaigns[cidx].name + '<br>' + "Successes: " + value.toString() + "%").show();
|
||||
});
|
||||
|
||||
$chart.on('mouseleave', '.ct-point', function() {
|
||||
$toolTip.hide();
|
||||
});
|
||||
$chart.on('mousemove', function(event) {
|
||||
$toolTip.css({
|
||||
left: (event.offsetX || event.originalEvent.layerX) - $toolTip.width() / 2 - 10,
|
||||
top: (event.offsetY + 40 || event.originalEvent.layerY) - $toolTip.height() - 40
|
||||
$piechart.on('mouseleave', '.ct-slice-donut', function() {
|
||||
$pietoolTip.hide();
|
||||
});
|
||||
});
|
||||
$("#overview_chart").on("click", ".ct-point", function(e) {
|
||||
var $cidx = $(this).attr('ct:meta');
|
||||
window.location.href = "/campaigns/" + campaigns[cidx].id
|
||||
});
|
||||
} else {
|
||||
$("#emptyMessage").show()
|
||||
}
|
||||
})
|
||||
.error(function(){
|
||||
errorFlash("Error fetching campaigns")
|
||||
})
|
||||
$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
|
||||
$chart = $("#overview_chart")
|
||||
var $toolTip = $chart
|
||||
.append('<div class="chartist-tooltip"></div>')
|
||||
.find('.chartist-tooltip')
|
||||
.hide();
|
||||
|
||||
$chart.on('mouseenter', '.ct-point', function() {
|
||||
var $point = $(this)
|
||||
value = $point.attr('ct:value') || 0
|
||||
cidx = $point.attr('ct:meta')
|
||||
$toolTip.html(campaigns[cidx].name + '<br>' + "Successes: " + value.toString() + "%").show();
|
||||
});
|
||||
|
||||
$chart.on('mouseleave', '.ct-point', function() {
|
||||
$toolTip.hide();
|
||||
});
|
||||
$chart.on('mousemove', function(event) {
|
||||
$toolTip.css({
|
||||
left: (event.offsetX || event.originalEvent.layerX) - $toolTip.width() / 2 - 10,
|
||||
top: (event.offsetY + 40 || event.originalEvent.layerY) - $toolTip.height() - 40
|
||||
});
|
||||
});
|
||||
$("#overview_chart").on("click", ".ct-point", function(e) {
|
||||
var $cidx = $(this).attr('ct:meta');
|
||||
window.location.href = "/campaigns/" + campaigns[cidx].id
|
||||
});
|
||||
} else {
|
||||
$("#emptyMessage").show()
|
||||
}
|
||||
})
|
||||
.error(function() {
|
||||
errorFlash("Error fetching campaigns")
|
||||
})
|
||||
})
|
||||
|
|
|
@ -4,72 +4,75 @@
|
|||
Author: Jordan Wright <github.com/jordan-wright>
|
||||
*/
|
||||
var pages = []
|
||||
|
||||
// Save attempts to POST to /templates/
|
||||
function save(idx){
|
||||
function save(idx) {
|
||||
var page = {}
|
||||
page.name = $("#name").val()
|
||||
page.html = CKEDITOR.instances["html_editor"].getData();
|
||||
if (idx != -1){
|
||||
if (idx != -1) {
|
||||
page.id = pages[idx].id
|
||||
api.pageId.put(page)
|
||||
.success(function(data){
|
||||
successFlash("Page edited successfully!")
|
||||
load()
|
||||
dismiss()
|
||||
})
|
||||
.success(function(data) {
|
||||
successFlash("Page edited successfully!")
|
||||
load()
|
||||
dismiss()
|
||||
})
|
||||
} else {
|
||||
// Submit the page
|
||||
api.pages.post(page)
|
||||
.success(function(data){
|
||||
successFlash("Page added successfully!")
|
||||
load()
|
||||
dismiss()
|
||||
})
|
||||
.error(function(data){
|
||||
modalError(data.responseJSON.message)
|
||||
})
|
||||
.success(function(data) {
|
||||
successFlash("Page added successfully!")
|
||||
load()
|
||||
dismiss()
|
||||
})
|
||||
.error(function(data) {
|
||||
modalError(data.responseJSON.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function dismiss(){
|
||||
function dismiss() {
|
||||
$("#modal\\.flashes").empty()
|
||||
$("#name").val("")
|
||||
$("#html_editor").val("")
|
||||
$("#newLandingPageModal").modal('hide')
|
||||
}
|
||||
|
||||
function deletePage(idx){
|
||||
if (confirm("Delete " + pages[idx].name + "?")){
|
||||
function deletePage(idx) {
|
||||
if (confirm("Delete " + pages[idx].name + "?")) {
|
||||
api.pageId.delete(pages[idx].id)
|
||||
.success(function(data){
|
||||
successFlash(data.message)
|
||||
load()
|
||||
})
|
||||
.success(function(data) {
|
||||
successFlash(data.message)
|
||||
load()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function importSite(){
|
||||
function importSite() {
|
||||
url = $("#url").val()
|
||||
if (!url){
|
||||
if (!url) {
|
||||
modalError("No URL Specified!")
|
||||
} else {
|
||||
api.clone_site({
|
||||
url: url,
|
||||
include_resources: false
|
||||
})
|
||||
.success(function(data){
|
||||
console.log($("#html_editor"))
|
||||
$("#html_editor").val(data.html)
|
||||
$("#importSiteModal").modal("hide")
|
||||
})
|
||||
.error(function(data){
|
||||
modalError(data.responseJSON.message)
|
||||
})
|
||||
url: url,
|
||||
include_resources: false
|
||||
})
|
||||
.success(function(data) {
|
||||
console.log($("#html_editor"))
|
||||
$("#html_editor").val(data.html)
|
||||
$("#importSiteModal").modal("hide")
|
||||
})
|
||||
.error(function(data) {
|
||||
modalError(data.responseJSON.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function edit(idx){
|
||||
$("#modalSubmit").unbind('click').click(function(){save(idx)})
|
||||
function edit(idx) {
|
||||
$("#modalSubmit").unbind('click').click(function() {
|
||||
save(idx)
|
||||
})
|
||||
$("#html_editor").ckeditor()
|
||||
var page = {}
|
||||
if (idx != -1) {
|
||||
|
@ -79,82 +82,80 @@ function edit(idx){
|
|||
}
|
||||
}
|
||||
|
||||
function load(){
|
||||
/*
|
||||
load() - Loads the current pages using the API
|
||||
*/
|
||||
function load() {
|
||||
/*
|
||||
load() - Loads the current pages using the API
|
||||
*/
|
||||
$("#pagesTable").hide()
|
||||
$("#emptyMessage").hide()
|
||||
$("#loading").show()
|
||||
api.pages.get()
|
||||
.success(function(ps){
|
||||
pages = ps
|
||||
$("#loading").hide()
|
||||
if (pages.length > 0){
|
||||
$("#pagesTable").show()
|
||||
pagesTable = $("#pagesTable").DataTable();
|
||||
pagesTable.clear()
|
||||
$.each(pages, function(i, page){
|
||||
pagesTable.row.add([
|
||||
page.name,
|
||||
moment(page.modified_date).format('MMMM Do YYYY, h:mm:ss a'),
|
||||
"<div class='pull-right'><button class='btn btn-primary' data-toggle='modal' data-target='#newLandingPageModal' onclick='edit(" + i + ")'>\
|
||||
.success(function(ps) {
|
||||
pages = ps
|
||||
$("#loading").hide()
|
||||
if (pages.length > 0) {
|
||||
$("#pagesTable").show()
|
||||
pagesTable = $("#pagesTable").DataTable();
|
||||
pagesTable.clear()
|
||||
$.each(pages, function(i, page) {
|
||||
pagesTable.row.add([
|
||||
page.name,
|
||||
moment(page.modified_date).format('MMMM Do YYYY, h:mm:ss a'),
|
||||
"<div class='pull-right'><button class='btn btn-primary' data-toggle='modal' data-target='#newLandingPageModal' onclick='edit(" + i + ")'>\
|
||||
<i class='fa fa-pencil'></i>\
|
||||
</button>\
|
||||
<button class='btn btn-danger' onclick='deletePage(" + i + ")'>\
|
||||
<i class='fa fa-trash-o'></i>\
|
||||
</button></div>"
|
||||
]).draw()
|
||||
})
|
||||
} else {
|
||||
$("#emptyMessage").show()
|
||||
}
|
||||
})
|
||||
.error(function(){
|
||||
$("#loading").hide()
|
||||
errorFlash("Error fetching pages")
|
||||
})
|
||||
]).draw()
|
||||
})
|
||||
} else {
|
||||
$("#emptyMessage").show()
|
||||
}
|
||||
})
|
||||
.error(function() {
|
||||
$("#loading").hide()
|
||||
errorFlash("Error fetching pages")
|
||||
})
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$(document).ready(function() {
|
||||
// Setup multiple modals
|
||||
// Code based on http://miles-by-motorcycle.com/static/bootstrap-modal/index.html
|
||||
$('.modal').on('hidden.bs.modal', function( event ) {
|
||||
$(this).removeClass( 'fv-modal-stack' );
|
||||
$('body').data( 'fv_open_modals', $('body').data( 'fv_open_modals' ) - 1 );
|
||||
$('.modal').on('hidden.bs.modal', function(event) {
|
||||
$(this).removeClass('fv-modal-stack');
|
||||
$('body').data('fv_open_modals', $('body').data('fv_open_modals') - 1);
|
||||
});
|
||||
$( '.modal' ).on( 'shown.bs.modal', function ( event ) {
|
||||
$('.modal').on('shown.bs.modal', function(event) {
|
||||
// Keep track of the number of open modals
|
||||
if ( typeof( $('body').data( 'fv_open_modals' ) ) == 'undefined' )
|
||||
{
|
||||
$('body').data( 'fv_open_modals', 0 );
|
||||
if (typeof($('body').data('fv_open_modals')) == 'undefined') {
|
||||
$('body').data('fv_open_modals', 0);
|
||||
}
|
||||
// if the z-index of this modal has been set, ignore.
|
||||
if ( $(this).hasClass( 'fv-modal-stack' ) )
|
||||
{
|
||||
if ($(this).hasClass('fv-modal-stack')) {
|
||||
return;
|
||||
}
|
||||
$(this).addClass( 'fv-modal-stack' );
|
||||
// Increment the number of open modals
|
||||
$('body').data( 'fv_open_modals', $('body').data( 'fv_open_modals' ) + 1 );
|
||||
// Setup the appropriate z-index
|
||||
$(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' );
|
||||
$(this).addClass('fv-modal-stack');
|
||||
// Increment the number of open modals
|
||||
$('body').data('fv_open_modals', $('body').data('fv_open_modals') + 1);
|
||||
// Setup the appropriate z-index
|
||||
$(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');
|
||||
});
|
||||
$.fn.modal.Constructor.prototype.enforceFocus = function() {
|
||||
$( document )
|
||||
.off( 'focusin.bs.modal' ) // guard against infinite focus loop
|
||||
.on( 'focusin.bs.modal', $.proxy( function( e ) {
|
||||
if (
|
||||
this.$element[ 0 ] !== e.target && !this.$element.has( e.target ).length
|
||||
// CKEditor compatibility fix start.
|
||||
&& !$( e.target ).closest( '.cke_dialog, .cke' ).length
|
||||
// CKEditor compatibility fix end.
|
||||
) {
|
||||
this.$element.trigger( 'focus' );
|
||||
}
|
||||
}, this ) );
|
||||
$(document)
|
||||
.off('focusin.bs.modal') // guard against infinite focus loop
|
||||
.on('focusin.bs.modal', $.proxy(function(e) {
|
||||
if (
|
||||
this.$element[0] !== e.target && !this.$element.has(e.target).length
|
||||
// CKEditor compatibility fix start.
|
||||
&& !$(e.target).closest('.cke_dialog, .cke').length
|
||||
// CKEditor compatibility fix end.
|
||||
) {
|
||||
this.$element.trigger('focus');
|
||||
}
|
||||
}, this));
|
||||
};
|
||||
load()
|
||||
})
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
$(document).ready(function(){
|
||||
$("#apiResetForm").submit(function(e){
|
||||
$(document).ready(function() {
|
||||
$("#apiResetForm").submit(function(e) {
|
||||
$.post("/api/reset", $(this).serialize())
|
||||
.done(function(data){
|
||||
api_key = data.data
|
||||
successFlash(data.message)
|
||||
$("#api_key").val(api_key)
|
||||
})
|
||||
.fail(function(data){
|
||||
errorFlash(data.message)
|
||||
})
|
||||
.done(function(data) {
|
||||
api_key = data.data
|
||||
successFlash(data.message)
|
||||
$("#api_key").val(api_key)
|
||||
})
|
||||
.fail(function(data) {
|
||||
errorFlash(data.message)
|
||||
})
|
||||
return false
|
||||
})
|
||||
$("#settingsForm").submit(function(e){
|
||||
$("#settingsForm").submit(function(e) {
|
||||
$.post("/settings", $(this).serialize())
|
||||
.done(function(data){
|
||||
successFlash(data.message)
|
||||
})
|
||||
.fail(function(data){
|
||||
errorFlash(data.responseJSON.message)
|
||||
})
|
||||
.done(function(data) {
|
||||
successFlash(data.message)
|
||||
})
|
||||
.fail(function(data) {
|
||||
errorFlash(data.responseJSON.message)
|
||||
})
|
||||
return false
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,64 +1,66 @@
|
|||
var templates = []
|
||||
var icons = {
|
||||
"application/vnd.ms-excel" : "fa-file-excel-o",
|
||||
"text/plain" : "fa-file-text-o",
|
||||
"image/gif" : "fa-file-image-o",
|
||||
"image/png" : "fa-file-image-o",
|
||||
"application/pdf" : "fa-file-pdf-o",
|
||||
"application/x-zip-compressed" : "fa-file-archive-o",
|
||||
"application/x-gzip" : "fa-file-archive-o",
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation" : "fa-file-powerpoint-o",
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document" : "fa-file-word-o",
|
||||
"application/octet-stream" : "fa-file-o",
|
||||
"application/x-msdownload" : "fa-file-o"
|
||||
"application/vnd.ms-excel": "fa-file-excel-o",
|
||||
"text/plain": "fa-file-text-o",
|
||||
"image/gif": "fa-file-image-o",
|
||||
"image/png": "fa-file-image-o",
|
||||
"application/pdf": "fa-file-pdf-o",
|
||||
"application/x-zip-compressed": "fa-file-archive-o",
|
||||
"application/x-gzip": "fa-file-archive-o",
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "fa-file-powerpoint-o",
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "fa-file-word-o",
|
||||
"application/octet-stream": "fa-file-o",
|
||||
"application/x-msdownload": "fa-file-o"
|
||||
}
|
||||
|
||||
// Save attempts to POST to /templates/
|
||||
function save(idx){
|
||||
var template = {attachments:[]}
|
||||
function save(idx) {
|
||||
var template = {
|
||||
attachments: []
|
||||
}
|
||||
template.name = $("#name").val()
|
||||
template.subject = $("#subject").val()
|
||||
template.html = CKEDITOR.instances["html_editor"].getData();
|
||||
// Fix the URL Scheme added by CKEditor (until we can remove it from the plugin)
|
||||
template.html = template.html.replace(/https?:\/\/{{\.URL}}/gi, "{{.URL}}")
|
||||
// If the "Add Tracker Image" checkbox is checked, add the tracker
|
||||
// If the "Add Tracker Image" checkbox is checked, add the tracker
|
||||
if ($("#use_tracker_checkbox").prop("checked") &&
|
||||
template.html.indexOf("{{.Tracker}}") == -1 &&
|
||||
template.html.indexOf("{{.TrackingUrl}}") == -1){
|
||||
template.html = template.html.replace("</body>", "{{.Tracker}}</body>")
|
||||
template.html.indexOf("{{.Tracker}}") == -1 &&
|
||||
template.html.indexOf("{{.TrackingUrl}}") == -1) {
|
||||
template.html = template.html.replace("</body>", "{{.Tracker}}</body>")
|
||||
}
|
||||
template.text = $("#text_editor").val()
|
||||
// Add the attachments
|
||||
$.each($("#attachmentsTable").DataTable().rows().data(), function(i, target){
|
||||
// Add the attachments
|
||||
$.each($("#attachmentsTable").DataTable().rows().data(), function(i, target) {
|
||||
template.attachments.push({
|
||||
name : target[1],
|
||||
name: target[1],
|
||||
content: target[3],
|
||||
type: target[4],
|
||||
})
|
||||
})
|
||||
if (idx != -1){
|
||||
if (idx != -1) {
|
||||
template.id = templates[idx].id
|
||||
api.templateId.put(template)
|
||||
.success(function(data){
|
||||
successFlash("Template edited successfully!")
|
||||
load()
|
||||
dismiss()
|
||||
})
|
||||
.success(function(data) {
|
||||
successFlash("Template edited successfully!")
|
||||
load()
|
||||
dismiss()
|
||||
})
|
||||
} else {
|
||||
// Submit the template
|
||||
api.templates.post(template)
|
||||
.success(function(data){
|
||||
successFlash("Template added successfully!")
|
||||
load()
|
||||
dismiss()
|
||||
})
|
||||
.error(function(data){
|
||||
modalError(data.responseJSON.message)
|
||||
})
|
||||
.success(function(data) {
|
||||
successFlash("Template added successfully!")
|
||||
load()
|
||||
dismiss()
|
||||
})
|
||||
.error(function(data) {
|
||||
modalError(data.responseJSON.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function dismiss(){
|
||||
function dismiss() {
|
||||
$("#modal\\.flashes").empty()
|
||||
$("#attachmentsTable").dataTable().DataTable().clear().draw()
|
||||
$("#name").val("")
|
||||
|
@ -67,24 +69,24 @@ function dismiss(){
|
|||
$("#modal").modal('hide')
|
||||
}
|
||||
|
||||
function deleteTemplate(idx){
|
||||
if (confirm("Delete " + templates[idx].name + "?")){
|
||||
function deleteTemplate(idx) {
|
||||
if (confirm("Delete " + templates[idx].name + "?")) {
|
||||
api.templateId.delete(templates[idx].id)
|
||||
.success(function(data){
|
||||
successFlash(data.message)
|
||||
load()
|
||||
})
|
||||
.success(function(data) {
|
||||
successFlash(data.message)
|
||||
load()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function attach(files){
|
||||
function attach(files) {
|
||||
attachmentsTable = $("#attachmentsTable").DataTable();
|
||||
$.each(files, function(i, file){
|
||||
$.each(files, function(i, file) {
|
||||
var reader = new FileReader();
|
||||
/* Make this a datatable */
|
||||
reader.onload = function(e){
|
||||
reader.onload = function(e) {
|
||||
var icon = icons[file.type] || "fa-file-o"
|
||||
// Add the record to the modal
|
||||
// Add the record to the modal
|
||||
attachmentsTable.row.add([
|
||||
'<i class="fa ' + icon + '"></i>',
|
||||
file.name,
|
||||
|
@ -100,33 +102,38 @@ function attach(files){
|
|||
})
|
||||
}
|
||||
|
||||
function edit(idx){
|
||||
$("#modalSubmit").unbind('click').click(function(){save(idx)})
|
||||
$("#attachmentUpload").unbind('click').click(function(){this.value=null})
|
||||
function edit(idx) {
|
||||
$("#modalSubmit").unbind('click').click(function() {
|
||||
save(idx)
|
||||
})
|
||||
$("#attachmentUpload").unbind('click').click(function() {
|
||||
this.value = null
|
||||
})
|
||||
$("#html_editor").ckeditor()
|
||||
$("#attachmentsTable").show()
|
||||
attachmentsTable = null
|
||||
if ( $.fn.dataTable.isDataTable('#attachmentsTable') ) {
|
||||
if ($.fn.dataTable.isDataTable('#attachmentsTable')) {
|
||||
attachmentsTable = $('#attachmentsTable').DataTable();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
attachmentsTable = $("#attachmentsTable").DataTable({
|
||||
"aoColumnDefs" : [{
|
||||
"targets" : [3,4],
|
||||
"sClass" : "datatable_hidden"
|
||||
"aoColumnDefs": [{
|
||||
"targets": [3, 4],
|
||||
"sClass": "datatable_hidden"
|
||||
}]
|
||||
});
|
||||
}
|
||||
var template = {attachments:[]}
|
||||
var template = {
|
||||
attachments: []
|
||||
}
|
||||
if (idx != -1) {
|
||||
template = templates[idx]
|
||||
$("#name").val(template.name)
|
||||
$("#subject").val(template.subject)
|
||||
$("#subject").val(template.subject)
|
||||
$("#html_editor").val(template.html)
|
||||
$("#text_editor").val(template.text)
|
||||
$.each(template.attachments, function(i, file){
|
||||
$.each(template.attachments, function(i, file) {
|
||||
var icon = icons[file.type] || "fa-file-o"
|
||||
// Add the record to the modal
|
||||
// Add the record to the modal
|
||||
attachmentsTable.row.add([
|
||||
'<i class="fa ' + icon + '"></i>',
|
||||
file.name,
|
||||
|
@ -137,110 +144,108 @@ function edit(idx){
|
|||
})
|
||||
}
|
||||
// Handle Deletion
|
||||
$("#attachmentsTable").unbind('click').on("click", "span>i.fa-trash-o", function(){
|
||||
attachmentsTable.row( $(this).parents('tr') )
|
||||
.remove()
|
||||
.draw();
|
||||
$("#attachmentsTable").unbind('click').on("click", "span>i.fa-trash-o", function() {
|
||||
attachmentsTable.row($(this).parents('tr'))
|
||||
.remove()
|
||||
.draw();
|
||||
})
|
||||
}
|
||||
|
||||
function importEmail(){
|
||||
function importEmail() {
|
||||
raw = $("#email_content").val()
|
||||
if (!raw){
|
||||
if (!raw) {
|
||||
modalError("No Content Specified!")
|
||||
} else {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/api/import/email",
|
||||
data: raw,
|
||||
dataType: "json",
|
||||
contentType: "text/plain"
|
||||
})
|
||||
.success(function(data){
|
||||
$("#text_editor").val(data.text)
|
||||
$("#html_editor").val(data.html)
|
||||
$("#subject").val(data.subject)
|
||||
$("#importEmailModal").modal("hide")
|
||||
})
|
||||
.error(function(data){
|
||||
modalError(data.responseJSON.message)
|
||||
})
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/api/import/email",
|
||||
data: raw,
|
||||
dataType: "json",
|
||||
contentType: "text/plain"
|
||||
})
|
||||
.success(function(data) {
|
||||
$("#text_editor").val(data.text)
|
||||
$("#html_editor").val(data.html)
|
||||
$("#subject").val(data.subject)
|
||||
$("#importEmailModal").modal("hide")
|
||||
})
|
||||
.error(function(data) {
|
||||
modalError(data.responseJSON.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function load(){
|
||||
function load() {
|
||||
$("#templateTable").hide()
|
||||
$("#emptyMessage").hide()
|
||||
$("#loading").show()
|
||||
api.templates.get()
|
||||
.success(function(ts){
|
||||
templates = ts
|
||||
$("#loading").hide()
|
||||
if (templates.length > 0){
|
||||
$("#templateTable").show()
|
||||
templateTable = $("#templateTable").DataTable();
|
||||
templateTable.clear()
|
||||
$.each(templates, function(i, template){
|
||||
templateTable.row.add([
|
||||
template.name,
|
||||
moment(template.modified_date).format('MMMM Do YYYY, h:mm:ss a'),
|
||||
"<div class='pull-right'><button class='btn btn-primary' data-toggle='modal' data-target='#modal' onclick='edit(" + i + ")'>\
|
||||
.success(function(ts) {
|
||||
templates = ts
|
||||
$("#loading").hide()
|
||||
if (templates.length > 0) {
|
||||
$("#templateTable").show()
|
||||
templateTable = $("#templateTable").DataTable();
|
||||
templateTable.clear()
|
||||
$.each(templates, function(i, template) {
|
||||
templateTable.row.add([
|
||||
template.name,
|
||||
moment(template.modified_date).format('MMMM Do YYYY, h:mm:ss a'),
|
||||
"<div class='pull-right'><button class='btn btn-primary' data-toggle='modal' data-target='#modal' onclick='edit(" + i + ")'>\
|
||||
<i class='fa fa-pencil'></i>\
|
||||
</button>\
|
||||
<button class='btn btn-danger' onclick='deleteTemplate(" + i + ")'>\
|
||||
<i class='fa fa-trash-o'></i>\
|
||||
</button></div>"
|
||||
]).draw()
|
||||
})
|
||||
} else {
|
||||
$("#emptyMessage").show()
|
||||
}
|
||||
})
|
||||
.error(function(){
|
||||
$("#loading").hide()
|
||||
errorFlash("Error fetching templates")
|
||||
})
|
||||
]).draw()
|
||||
})
|
||||
} else {
|
||||
$("#emptyMessage").show()
|
||||
}
|
||||
})
|
||||
.error(function() {
|
||||
$("#loading").hide()
|
||||
errorFlash("Error fetching templates")
|
||||
})
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$(document).ready(function() {
|
||||
// Setup multiple modals
|
||||
// Code based on http://miles-by-motorcycle.com/static/bootstrap-modal/index.html
|
||||
$('.modal').on('hidden.bs.modal', function( event ) {
|
||||
$(this).removeClass( 'fv-modal-stack' );
|
||||
$('body').data( 'fv_open_modals', $('body').data( 'fv_open_modals' ) - 1 );
|
||||
$('.modal').on('hidden.bs.modal', function(event) {
|
||||
$(this).removeClass('fv-modal-stack');
|
||||
$('body').data('fv_open_modals', $('body').data('fv_open_modals') - 1);
|
||||
});
|
||||
$( '.modal' ).on( 'shown.bs.modal', function ( event ) {
|
||||
$('.modal').on('shown.bs.modal', function(event) {
|
||||
// Keep track of the number of open modals
|
||||
if ( typeof( $('body').data( 'fv_open_modals' ) ) == 'undefined' )
|
||||
{
|
||||
$('body').data( 'fv_open_modals', 0 );
|
||||
if (typeof($('body').data('fv_open_modals')) == 'undefined') {
|
||||
$('body').data('fv_open_modals', 0);
|
||||
}
|
||||
// if the z-index of this modal has been set, ignore.
|
||||
if ( $(this).hasClass( 'fv-modal-stack' ) )
|
||||
{
|
||||
if ($(this).hasClass('fv-modal-stack')) {
|
||||
return;
|
||||
}
|
||||
$(this).addClass( 'fv-modal-stack' );
|
||||
// Increment the number of open modals
|
||||
$('body').data( 'fv_open_modals', $('body').data( 'fv_open_modals' ) + 1 );
|
||||
// Setup the appropriate z-index
|
||||
$(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' );
|
||||
$(this).addClass('fv-modal-stack');
|
||||
// Increment the number of open modals
|
||||
$('body').data('fv_open_modals', $('body').data('fv_open_modals') + 1);
|
||||
// Setup the appropriate z-index
|
||||
$(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');
|
||||
});
|
||||
$.fn.modal.Constructor.prototype.enforceFocus = function() {
|
||||
$( document )
|
||||
.off( 'focusin.bs.modal' ) // guard against infinite focus loop
|
||||
.on( 'focusin.bs.modal', $.proxy( function( e ) {
|
||||
if (
|
||||
this.$element[ 0 ] !== e.target && !this.$element.has( e.target ).length
|
||||
// CKEditor compatibility fix start.
|
||||
&& !$( e.target ).closest( '.cke_dialog, .cke' ).length
|
||||
// CKEditor compatibility fix end.
|
||||
) {
|
||||
this.$element.trigger( 'focus' );
|
||||
}
|
||||
}, this ) );
|
||||
$(document)
|
||||
.off('focusin.bs.modal') // guard against infinite focus loop
|
||||
.on('focusin.bs.modal', $.proxy(function(e) {
|
||||
if (
|
||||
this.$element[0] !== e.target && !this.$element.has(e.target).length
|
||||
// CKEditor compatibility fix start.
|
||||
&& !$(e.target).closest('.cke_dialog, .cke').length
|
||||
// CKEditor compatibility fix end.
|
||||
) {
|
||||
this.$element.trigger('focus');
|
||||
}
|
||||
}, this));
|
||||
};
|
||||
load()
|
||||
})
|
||||
|
|
|
@ -1,60 +1,62 @@
|
|||
var groups = []
|
||||
|
||||
// Save attempts to POST or PUT to /groups/
|
||||
function save(idx){
|
||||
function save(idx) {
|
||||
var targets = []
|
||||
$.each($("#targetsTable").DataTable().rows().data(), function(i, target){
|
||||
$.each($("#targetsTable").DataTable().rows().data(), function(i, target) {
|
||||
targets.push({
|
||||
first_name : target[0],
|
||||
first_name: target[0],
|
||||
last_name: target[1],
|
||||
email: target[2],
|
||||
position: target[3]
|
||||
})
|
||||
})
|
||||
var group = {
|
||||
name: $("#name").val(),
|
||||
targets: targets
|
||||
}
|
||||
// Submit the group
|
||||
name: $("#name").val(),
|
||||
targets: targets
|
||||
}
|
||||
// Submit the group
|
||||
if (idx != -1) {
|
||||
// If we're just editing an existing group,
|
||||
// we need to PUT /groups/:id
|
||||
group.id = groups[idx].id
|
||||
api.groupId.put(group)
|
||||
.success(function(data){
|
||||
successFlash("Group updated successfully!")
|
||||
load()
|
||||
dismiss()
|
||||
$("#modal").modal('hide')
|
||||
})
|
||||
.error(function(data){
|
||||
modalError(data.responseJSON.message)
|
||||
})
|
||||
.success(function(data) {
|
||||
successFlash("Group updated successfully!")
|
||||
load()
|
||||
dismiss()
|
||||
$("#modal").modal('hide')
|
||||
})
|
||||
.error(function(data) {
|
||||
modalError(data.responseJSON.message)
|
||||
})
|
||||
} else {
|
||||
// Else, if this is a new group, POST it
|
||||
// to /groups
|
||||
api.groups.post(group)
|
||||
.success(function(data){
|
||||
successFlash("Group added successfully!")
|
||||
load()
|
||||
dismiss()
|
||||
$("#modal").modal('hide')
|
||||
})
|
||||
.error(function(data){
|
||||
modalError(data.responseJSON.message)
|
||||
})
|
||||
.success(function(data) {
|
||||
successFlash("Group added successfully!")
|
||||
load()
|
||||
dismiss()
|
||||
$("#modal").modal('hide')
|
||||
})
|
||||
.error(function(data) {
|
||||
modalError(data.responseJSON.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function dismiss(){
|
||||
function dismiss() {
|
||||
$("#targetsTable").dataTable().DataTable().clear().draw()
|
||||
$("#name").val("")
|
||||
$("#modal\\.flashes").empty()
|
||||
}
|
||||
|
||||
function edit(idx){
|
||||
function edit(idx) {
|
||||
targets = $("#targetsTable").dataTable()
|
||||
$("#modalSubmit").unbind('click').click(function(){save(idx)})
|
||||
$("#modalSubmit").unbind('click').click(function() {
|
||||
save(idx)
|
||||
})
|
||||
if (idx == -1) {
|
||||
group = {}
|
||||
} else {
|
||||
|
@ -62,31 +64,6 @@ function edit(idx){
|
|||
$("#name").val(group.name)
|
||||
$.each(group.targets, function(i, record) {
|
||||
targets.DataTable()
|
||||
.row.add([
|
||||
record.first_name,
|
||||
record.last_name,
|
||||
record.email,
|
||||
record.position,
|
||||
'<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>'
|
||||
]).draw()
|
||||
});
|
||||
}
|
||||
// Handle file uploads
|
||||
$("#csvupload").fileupload({
|
||||
dataType:"json",
|
||||
add: function(e, data){
|
||||
$("#modal\\.flashes").empty()
|
||||
var acceptFileTypes= /(csv|txt)$/i;
|
||||
var filename = data.originalFiles[0]['name']
|
||||
if (filename && !acceptFileTypes.test(filename.split(".").pop())) {
|
||||
modalError("Unsupported file extension (use .csv or .txt)")
|
||||
return false;
|
||||
}
|
||||
data.submit();
|
||||
},
|
||||
done: function(e, data){
|
||||
$.each(data.result, function(i, record) {
|
||||
targets.DataTable()
|
||||
.row.add([
|
||||
record.first_name,
|
||||
record.last_name,
|
||||
|
@ -94,90 +71,115 @@ function edit(idx){
|
|||
record.position,
|
||||
'<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>'
|
||||
]).draw()
|
||||
});
|
||||
}
|
||||
// Handle file uploads
|
||||
$("#csvupload").fileupload({
|
||||
dataType: "json",
|
||||
add: function(e, data) {
|
||||
$("#modal\\.flashes").empty()
|
||||
var acceptFileTypes = /(csv|txt)$/i;
|
||||
var filename = data.originalFiles[0]['name']
|
||||
if (filename && !acceptFileTypes.test(filename.split(".").pop())) {
|
||||
modalError("Unsupported file extension (use .csv or .txt)")
|
||||
return false;
|
||||
}
|
||||
data.submit();
|
||||
},
|
||||
done: function(e, data) {
|
||||
$.each(data.result, function(i, record) {
|
||||
targets.DataTable()
|
||||
.row.add([
|
||||
record.first_name,
|
||||
record.last_name,
|
||||
record.email,
|
||||
record.position,
|
||||
'<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>'
|
||||
]).draw()
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function deleteGroup(idx){
|
||||
if (confirm("Delete " + groups[idx].name + "?")){
|
||||
function deleteGroup(idx) {
|
||||
if (confirm("Delete " + groups[idx].name + "?")) {
|
||||
api.groupId.delete(groups[idx].id)
|
||||
.success(function(data){
|
||||
successFlash(data.message)
|
||||
load()
|
||||
})
|
||||
.success(function(data) {
|
||||
successFlash(data.message)
|
||||
load()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function load(){
|
||||
function load() {
|
||||
$("#groupTable").hide()
|
||||
$("#emptyMessage").hide()
|
||||
$("#loading").show()
|
||||
api.groups.get()
|
||||
.success(function(gs){
|
||||
$("#loading").hide()
|
||||
if (gs.length > 0){
|
||||
groups = gs
|
||||
$("#emptyMessage").hide()
|
||||
$("#groupTable").show()
|
||||
groupTable = $("#groupTable").DataTable();
|
||||
groupTable.clear();
|
||||
$.each(groups, function(i, group){
|
||||
var targets = ""
|
||||
$.each(group.targets, function(i, target){
|
||||
targets += target.email + ", "
|
||||
if (targets.length > 50) {
|
||||
targets = targets.slice(0,-3) + "..."
|
||||
return false;
|
||||
}
|
||||
})
|
||||
groupTable.row.add([
|
||||
group.name,
|
||||
targets,
|
||||
moment(group.modified_date).format('MMMM Do YYYY, h:mm:ss a'),
|
||||
"<div class='pull-right'><button class='btn btn-primary' data-toggle='modal' data-target='#modal' onclick='edit(" + i + ")'>\
|
||||
.success(function(gs) {
|
||||
$("#loading").hide()
|
||||
if (gs.length > 0) {
|
||||
groups = gs
|
||||
$("#emptyMessage").hide()
|
||||
$("#groupTable").show()
|
||||
groupTable = $("#groupTable").DataTable();
|
||||
groupTable.clear();
|
||||
$.each(groups, function(i, group) {
|
||||
var targets = ""
|
||||
$.each(group.targets, function(i, target) {
|
||||
targets += target.email + ", "
|
||||
if (targets.length > 50) {
|
||||
targets = targets.slice(0, -3) + "..."
|
||||
return false;
|
||||
}
|
||||
})
|
||||
groupTable.row.add([
|
||||
group.name,
|
||||
targets,
|
||||
moment(group.modified_date).format('MMMM Do YYYY, h:mm:ss a'),
|
||||
"<div class='pull-right'><button class='btn btn-primary' data-toggle='modal' data-target='#modal' onclick='edit(" + i + ")'>\
|
||||
<i class='fa fa-pencil'></i>\
|
||||
</button>\
|
||||
<button class='btn btn-danger' onclick='deleteGroup(" + i + ")'>\
|
||||
<i class='fa fa-trash-o'></i>\
|
||||
</button></div>"
|
||||
]).draw()
|
||||
})
|
||||
} else {
|
||||
$("#emptyMessage").show()
|
||||
}
|
||||
})
|
||||
.error(function(){
|
||||
errorFlash("Error fetching groups")
|
||||
})
|
||||
]).draw()
|
||||
})
|
||||
} else {
|
||||
$("#emptyMessage").show()
|
||||
}
|
||||
})
|
||||
.error(function() {
|
||||
errorFlash("Error fetching groups")
|
||||
})
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$(document).ready(function() {
|
||||
load()
|
||||
// Setup the event listeners
|
||||
// Handle manual additions
|
||||
$("#targetForm").submit(function(){
|
||||
// Setup the event listeners
|
||||
// Handle manual additions
|
||||
$("#targetForm").submit(function() {
|
||||
targets.DataTable()
|
||||
.row.add([
|
||||
$("#firstName").val(),
|
||||
$("#lastName").val(),
|
||||
$("#email").val(),
|
||||
$("#position").val(),
|
||||
'<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>'
|
||||
])
|
||||
.draw()
|
||||
$("#targetForm>div>input").val('')
|
||||
$("#firstName").focus()
|
||||
return false
|
||||
})
|
||||
// Handle Deletion
|
||||
$("#targetsTable").on("click", "span>i.fa-trash-o", function() {
|
||||
targets.DataTable()
|
||||
.row.add([
|
||||
$("#firstName").val(),
|
||||
$("#lastName").val(),
|
||||
$("#email").val(),
|
||||
$("#position").val(),
|
||||
'<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>'
|
||||
])
|
||||
.draw()
|
||||
$("#targetForm>div>input").val('')
|
||||
$("#firstName").focus()
|
||||
return false
|
||||
.row($(this).parents('tr'))
|
||||
.remove()
|
||||
.draw();
|
||||
})
|
||||
// Handle Deletion
|
||||
$("#targetsTable").on("click", "span>i.fa-trash-o", function(){
|
||||
targets.DataTable()
|
||||
.row( $(this).parents('tr') )
|
||||
.remove()
|
||||
.draw();
|
||||
})
|
||||
$("#modal").on("hide.bs.modal", function(){
|
||||
dismiss()
|
||||
$("#modal").on("hide.bs.modal", function() {
|
||||
dismiss()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
function errorFlash(message) {
|
||||
$("#flashes").empty()
|
||||
$("#flashes").append("<div style=\"text-align:center\" class=\"alert alert-danger\">\
|
||||
<i class=\"fa fa-exclamation-circle\"></i> " + message + "</div>"
|
||||
)
|
||||
<i class=\"fa fa-exclamation-circle\"></i> " + message + "</div>")
|
||||
}
|
||||
|
||||
function successFlash(message) {
|
||||
$("#flashes").empty()
|
||||
$("#flashes").append("<div style=\"text-align:center\" class=\"alert alert-success\">\
|
||||
<i class=\"fa fa-check-circle\"></i> " + message + "</div>"
|
||||
)
|
||||
<i class=\"fa fa-check-circle\"></i> " + message + "</div>")
|
||||
}
|
||||
|
||||
function modalError(message){
|
||||
function modalError(message) {
|
||||
$("#modal\\.flashes").empty().append("<div style=\"text-align:center\" class=\"alert alert-danger\">\
|
||||
<i class=\"fa fa-exclamation-circle\"></i> " + message + "</div>")
|
||||
}
|
||||
|
@ -23,7 +21,7 @@ function query(endpoint, method, data) {
|
|||
async: false,
|
||||
method: method,
|
||||
data: JSON.stringify(data),
|
||||
dataType:"json",
|
||||
dataType: "json",
|
||||
contentType: "application/json"
|
||||
})
|
||||
}
|
||||
|
@ -33,117 +31,117 @@ Define our API Endpoints
|
|||
*/
|
||||
var api = {
|
||||
// campaigns contains the endpoints for /campaigns
|
||||
campaigns : {
|
||||
campaigns: {
|
||||
// get() - Queries the API for GET /campaigns
|
||||
get: function(){
|
||||
get: function() {
|
||||
return query("/campaigns/", "GET", {})
|
||||
},
|
||||
// post() - Posts a campaign to POST /campaigns
|
||||
post: function(data){
|
||||
post: function(data) {
|
||||
return query("/campaigns/", "POST", data)
|
||||
}
|
||||
},
|
||||
// campaignId contains the endpoints for /campaigns/:id
|
||||
campaignId : {
|
||||
campaignId: {
|
||||
// get() - Queries the API for GET /campaigns/:id
|
||||
get: function(id){
|
||||
get: function(id) {
|
||||
return query("/campaigns/" + id, "GET", {})
|
||||
},
|
||||
// delete() - Deletes a campaign at DELETE /campaigns/:id
|
||||
delete: function(id){
|
||||
delete: function(id) {
|
||||
return query("/campaigns/" + id, "DELETE", data)
|
||||
}
|
||||
},
|
||||
// groups contains the endpoints for /groups
|
||||
groups : {
|
||||
groups: {
|
||||
// get() - Queries the API for GET /groups
|
||||
get: function(){
|
||||
get: function() {
|
||||
return query("/groups/", "GET", {})
|
||||
},
|
||||
// post() - Posts a campaign to POST /groups
|
||||
post: function(group){
|
||||
post: function(group) {
|
||||
return query("/groups/", "POST", group)
|
||||
}
|
||||
},
|
||||
// groupId contains the endpoints for /groups/:id
|
||||
groupId : {
|
||||
groupId: {
|
||||
// get() - Queries the API for GET /groups/:id
|
||||
get: function(id){
|
||||
get: function(id) {
|
||||
return query("/groups/" + id, "GET", {})
|
||||
},
|
||||
// put() - Puts a campaign to PUT /groups/:id
|
||||
put: function (group){
|
||||
put: function(group) {
|
||||
return query("/groups/" + group.id, "PUT", group)
|
||||
},
|
||||
// delete() - Deletes a campaign at DELETE /groups/:id
|
||||
delete: function(id){
|
||||
delete: function(id) {
|
||||
return query("/groups/" + id, "DELETE", {})
|
||||
}
|
||||
},
|
||||
// templates contains the endpoints for /templates
|
||||
templates : {
|
||||
templates: {
|
||||
// get() - Queries the API for GET /templates
|
||||
get: function(){
|
||||
get: function() {
|
||||
return query("/templates/", "GET", {})
|
||||
},
|
||||
// post() - Posts a campaign to POST /templates
|
||||
post: function(template){
|
||||
post: function(template) {
|
||||
return query("/templates/", "POST", template)
|
||||
}
|
||||
},
|
||||
// templateId contains the endpoints for /templates/:id
|
||||
templateId : {
|
||||
templateId: {
|
||||
// get() - Queries the API for GET /templates/:id
|
||||
get: function(id){
|
||||
get: function(id) {
|
||||
return query("/templates/" + id, "GET", {})
|
||||
},
|
||||
// put() - Puts a campaign to PUT /templates/:id
|
||||
put: function (template){
|
||||
put: function(template) {
|
||||
return query("/templates/" + template.id, "PUT", template)
|
||||
},
|
||||
// delete() - Deletes a campaign at DELETE /templates/:id
|
||||
delete: function(id){
|
||||
delete: function(id) {
|
||||
return query("/templates/" + id, "DELETE", {})
|
||||
}
|
||||
},
|
||||
// pages contains the endpoints for /pages
|
||||
pages : {
|
||||
pages: {
|
||||
// get() - Queries the API for GET /pages
|
||||
get: function(){
|
||||
get: function() {
|
||||
return query("/pages/", "GET", {})
|
||||
},
|
||||
// post() - Posts a campaign to POST /pages
|
||||
post: function(page){
|
||||
post: function(page) {
|
||||
return query("/pages/", "POST", page)
|
||||
}
|
||||
},
|
||||
// templateId contains the endpoints for /templates/:id
|
||||
pageId : {
|
||||
pageId: {
|
||||
// get() - Queries the API for GET /templates/:id
|
||||
get: function(id){
|
||||
get: function(id) {
|
||||
return query("/pages/" + id, "GET", {})
|
||||
},
|
||||
// put() - Puts a campaign to PUT /templates/:id
|
||||
put: function (page){
|
||||
put: function(page) {
|
||||
return query("/pages/" + page.id, "PUT", page)
|
||||
},
|
||||
// delete() - Deletes a campaign at DELETE /templates/:id
|
||||
delete: function(id){
|
||||
delete: function(id) {
|
||||
return query("/pages/" + id, "DELETE", {})
|
||||
}
|
||||
},
|
||||
// import handles all of the "import" functions in the api
|
||||
import_email : function(raw) {
|
||||
return query("/import/email", "POST", {})
|
||||
import_email: function(raw) {
|
||||
return query("/import/email", "POST", {})
|
||||
},
|
||||
clone_site : function(req){
|
||||
return query("/import/site", "POST", req)
|
||||
clone_site: function(req) {
|
||||
return query("/import/site", "POST", req)
|
||||
}
|
||||
}
|
||||
|
||||
// Register our moment.js datatables listeners
|
||||
$(document).ready(function(){
|
||||
$.fn.dataTable.moment('MMMM Do YYYY, h:mm:ss a');
|
||||
// Setup tooltips
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
$(document).ready(function() {
|
||||
$.fn.dataTable.moment('MMMM Do YYYY, h:mm:ss a');
|
||||
// Setup tooltips
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue