Initial commit: CloudOps infrastructure platform
This commit is contained in:
@@ -0,0 +1 @@
|
||||
{"stat":{"id":8,"emailAddress":"test@test.com","ipAddress":{},"dateSent":"2015-08-26T01:34:37+00:00","isRead":true,"isFailed":false,"dateRead":"2015-08-26T01:35:53+00:00","retryCount":0,"source":"email","openCount":1,"lastOpened":"2015-08-26T01:35:53+00:00","sourceId":5,"trackingHash":"55dd17adace91","viewedInBrowser":false,"lead":{"id":26,"points":10,"color":"","fields":{"core":{"title":{"id":"1","label":"Title","alias":"title","type":"lookup","group":"core","value":""},"firstname":{"id":"2","label":"First Name","alias":"firstname","type":"text","group":"core","value":""},"lastname":{"id":"3","label":"Last Name","alias":"lastname","type":"text","group":"core","value":""},"company":{"id":"4","label":"Company","alias":"company","type":"lookup","group":"core","value":""},"position":{"id":"5","label":"Position","alias":"position","type":"text","group":"core","value":""},"email":{"id":"6","label":"Email","alias":"email","type":"email","group":"core","value":"test@test.com"},"phone":{"id":"7","label":"Phone","alias":"phone","type":"tel","group":"core","value":""},"mobile":{"id":"8","label":"Mobile","alias":"mobile","type":"tel","group":"core","value":""},"fax":{"id":"9","label":"Fax","alias":"fax","type":"text","group":"core","value":""},"address1":{"id":"10","label":"Address Line 1","alias":"address1","type":"text","group":"core","value":""},"address2":{"id":"11","label":"Address Line 2","alias":"address2","type":"text","group":"core","value":""},"city":{"id":"12","label":"City","alias":"city","type":"lookup","group":"core","value":""},"state":{"id":"13","label":"State","alias":"state","type":"region","group":"core","value":""},"zipcode":{"id":"14","label":"Zipcode","alias":"zipcode","type":"lookup","group":"core","value":""},"country":{"id":"15","label":"Country","alias":"country","type":"country","group":"core","value":""},"website":{"id":"16","label":"Website","alias":"website","type":"text","group":"core","value":""}},"social":{"twitter":{"id":"17","label":"Twitter","alias":"twitter","type":"text","group":"social","value":""},"facebook":{"id":"18","label":"Facebook","alias":"facebook","type":"text","group":"social","value":""},"skype":{"id":"20","label":"Skype","alias":"skype","type":"text","group":"social","value":""},"instagram":{"id":"21","label":"Instagram","alias":"instagram","type":"text","group":"social","value":""},"foursquare":{"id":"22","label":"Foursquare","alias":"foursquare","type":"text","group":"social","value":""}},"personal":[],"professional":[]}},"email":{"id":5,"name":"Email","subject":"Email","language":"en","category":null,"fromAddress":null,"fromName":null,"replyToAddress":null,"bccAddress":null,"publishUp":null,"publishDown":null,"readCount":1,"sentCount":3,"revision":1,"assetAttachments":[],"variantStartDate":null,"variantSentCount":0,"variantReadCount":0,"variantParent":null,"variantChildren":[]}}}
|
||||
@@ -0,0 +1,45 @@
|
||||
/* EmailBundle */
|
||||
|
||||
.col-email-id {
|
||||
width: 75px;
|
||||
}
|
||||
|
||||
.email-builder .builder-panel .panel-body {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.table-bordered {
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.table-bordered.email-list > thead > tr > th:first-child, .table-bordered.email-list > tbody > tr > td:first-child,
|
||||
.table-bordered.email-template > thead > tr > th:first-child, .table-bordered.email-template > tbody > tr > td:first-child {
|
||||
border-left: 0px;
|
||||
}
|
||||
|
||||
.table-bordered.email-list > thead > tr > th:last-child, .table-bordered.email-list > tbody > tr > td:last-child,
|
||||
.table-bordered.email-template > thead > tr > th:last-child, .table-bordered.email-template > tbody > tr > td:last-child {
|
||||
border-right: 0px;
|
||||
}
|
||||
|
||||
.email-filters {
|
||||
|
||||
}
|
||||
|
||||
.clickable-stat a { color: #fff; }
|
||||
.clickable-stat a:hover { color: #fff; }
|
||||
|
||||
#emailGraphStats .spinner,
|
||||
#reads-map-container .spinner{
|
||||
text-align: center;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.dynamic-content .nav-tabs {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
white-space: nowrap;
|
||||
flex-wrap: nowrap;
|
||||
display: flex;
|
||||
scrollbar-width: thin; /* Firefox */
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
@media (min-width: 768px) {
|
||||
.modal-dialog-heatmap {
|
||||
width: 90%;
|
||||
max-width: 1200px;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-heatmap-close {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 20px;
|
||||
color: #fff;
|
||||
z-index: 1080;
|
||||
float: none;
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.modal-heatmap-close:hover,
|
||||
.modal-heatmap-close:focus {
|
||||
opacity: 1;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
|
||||
.heatmap-iframe {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.heatmap-iframe {
|
||||
height: 90vh;
|
||||
}
|
||||
}
|
||||
|
||||
body.heatmap-iframe-body a.heatmap-link {
|
||||
position: relative;
|
||||
z-index: 1010;
|
||||
}
|
||||
|
||||
.heatmap-label {
|
||||
position: absolute;
|
||||
z-index: 1050;
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
|
||||
.heatmap-label > p {
|
||||
padding: 6px 6px 4px 6px !important;
|
||||
margin: 0 !important;
|
||||
font-family: "Open Sans", Helvetica, Arial, sans-serif !important;
|
||||
font-size: 12px !important;
|
||||
line-height: 1 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.heatmap-legend {
|
||||
display: none;
|
||||
position: absolute;
|
||||
z-index: 1060;
|
||||
right: 20px;
|
||||
top: 30px;
|
||||
color: #fff;
|
||||
padding: 15px;
|
||||
background-color: rgba(0, 0, 0, 0.85);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.heatmap-legend {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.heatmap-legend a {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
.heatmap-legend a.active,
|
||||
.heatmap-legend a:focus,
|
||||
.heatmap-legend a:hover {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.heatmap-legend > p:nth-child(1),
|
||||
.heatmap-legend > p:nth-child(3) {
|
||||
color: #cccccc;
|
||||
font-size: 18px;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.heatmap-legend > p:nth-child(1) {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.heatmap-legend > p:nth-child(2) {
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.heatmap-legend > p:nth-child(3) {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.heatmap-scale {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.heatmap-scale-header,
|
||||
.heatmap-scale-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.heatmap-scale-footer {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.heatmap-scale-header > div,
|
||||
.heatmap-scale-footer > div {
|
||||
|
||||
}
|
||||
|
||||
.heatmap-scale-bar {
|
||||
position: relative;
|
||||
width: 47px;
|
||||
height: 16px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.heatmap-scale-bar:nth-child(1) {
|
||||
background: linear-gradient(to right, #2c3bb6, #0a85ff);
|
||||
border-radius: 2px 0 0 2px;
|
||||
}
|
||||
|
||||
.heatmap-scale-bar:nth-child(2) {
|
||||
background: linear-gradient(to right, #0a85ff, #f0df42);
|
||||
}
|
||||
|
||||
.heatmap-scale-bar:nth-child(3) {
|
||||
background: linear-gradient(to right, #f0df42, #f8c344);
|
||||
}
|
||||
|
||||
.heatmap-scale-bar:nth-child(4) {
|
||||
background: linear-gradient(to right, #f8c344, #ff843a);
|
||||
}
|
||||
|
||||
.heatmap-scale-bar:nth-child(5) {
|
||||
background: linear-gradient(to right, #ff843a, #f83834);
|
||||
border-radius: 0 2px 2px 0;
|
||||
}
|
||||
|
||||
.heatmap-scale-bar:nth-child(-n+4):after {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 1px;
|
||||
height: 24px;
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
position: absolute;
|
||||
top: -4px;
|
||||
right: -1px;
|
||||
z-index: 1;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
//EmailBundle (Copied from app/bundles/LeadBundle/Assets/js/lead.js)
|
||||
Mautic.emailBatchSubmit = function() {
|
||||
if (Mautic.batchActionPrecheck("")) {
|
||||
if (mQuery('#email_batch_newCategory').val()) {
|
||||
const $emailBatchIds = mQuery('#email_batch_ids');
|
||||
if ($emailBatchIds.length) {
|
||||
$emailBatchIds.val(Mautic.getCheckedListIds(false, true));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
function setCategory(id, newCategory) {
|
||||
const tr = document.querySelector("#row_email_" + id);
|
||||
const div = tr.querySelector("div.d-flex.ai-center.gap-xs");
|
||||
const span = div.querySelector("span");
|
||||
|
||||
div.textContent = newCategory.name;
|
||||
span.style = "background: #" + newCategory.color + ";"
|
||||
|
||||
div.prepend(span);
|
||||
}
|
||||
|
||||
Mautic.emailBatchSubmitCallback = function( response ) {
|
||||
mQuery('#MauticSharedModal').modal('hide');
|
||||
console.log("Received: " + JSON.stringify(response));
|
||||
response.affected.forEach( function(id){
|
||||
setCategory(id, response.newCategory);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
Mautic.testMonitoredEmailServerConnection = function(mailbox) {
|
||||
var data = {
|
||||
host: mQuery('#config_emailconfig_monitored_email_' + mailbox + '_host').val(),
|
||||
port: mQuery('#config_emailconfig_monitored_email_' + mailbox + '_port').val(),
|
||||
encryption: mQuery('#config_emailconfig_monitored_email_' + mailbox + '_encryption').val(),
|
||||
user: mQuery('#config_emailconfig_monitored_email_' + mailbox + '_user').val(),
|
||||
password: mQuery('#config_emailconfig_monitored_email_' + mailbox + '_password').val(),
|
||||
mailbox: mailbox
|
||||
};
|
||||
|
||||
var abortCall = false;
|
||||
if (!data.host) {
|
||||
mQuery('#config_emailconfig_monitored_email_' + mailbox + '_host').parent().addClass('has-error');
|
||||
abortCall = true;
|
||||
} else {
|
||||
mQuery('#config_emailconfig_monitored_email_' + mailbox + '_host').parent().removeClass('has-error');
|
||||
}
|
||||
|
||||
if (!data.port) {
|
||||
mQuery('#config_emailconfig_monitored_email_' + mailbox + '_port').parent().addClass('has-error');
|
||||
abortCall = true;
|
||||
} else {
|
||||
mQuery('#config_emailconfig_monitored_email_' + mailbox + '_port').parent().removeClass('has-error');
|
||||
}
|
||||
|
||||
if (abortCall) {
|
||||
return;
|
||||
}
|
||||
|
||||
mQuery('#' + mailbox + 'TestButtonContainer .ri-loader-3-line').removeClass('hide');
|
||||
|
||||
Mautic.ajaxActionRequest('email:testMonitoredEmailServerConnection', data, function(response) {
|
||||
var theClass = (response.success) ? 'has-success' : 'has-error';
|
||||
var theMessage = response.message;
|
||||
mQuery('#' + mailbox + 'TestButtonContainer').removeClass('has-success has-error').addClass(theClass);
|
||||
mQuery('#' + mailbox + 'TestButtonContainer .help-block').html(theMessage);
|
||||
mQuery('#' + mailbox + 'TestButtonContainer .ri-loader-3-line').addClass('hide');
|
||||
|
||||
if (response.folders) {
|
||||
if (mailbox == 'general') {
|
||||
// Update applicable folders
|
||||
mQuery('select[data-imap-folders]').each(
|
||||
function(index) {
|
||||
var thisMailbox = mQuery(this).data('imap-folders');
|
||||
if (mQuery('#config_emailconfig_monitored_email_' + thisMailbox + '_override_settings_0').is(':checked')) {
|
||||
var folder = '#config_emailconfig_monitored_email_' + thisMailbox + '_folder';
|
||||
var curVal = mQuery(folder).val();
|
||||
mQuery(folder).html(response.folders);
|
||||
mQuery(folder).val(curVal);
|
||||
mQuery(folder).trigger('chosen:updated');
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
// Find and update folder lists
|
||||
var folder = '#config_emailconfig_monitored_email_' + mailbox + '_folder';
|
||||
var curVal = mQuery(folder).val();
|
||||
mQuery(folder).html(response.folders);
|
||||
mQuery(folder).val(curVal);
|
||||
mQuery(folder).trigger('chosen:updated');
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Mautic.disableSendTestEmailButton = function(element) {
|
||||
mQuery(element).closest('.tab-pane').find('.config-dsn-test-container').each(function () {Mautic.configDsnTestDisable(this)});
|
||||
};
|
||||
@@ -0,0 +1,755 @@
|
||||
/** EmailBundle **/
|
||||
Mautic.emailOnLoad = function (container, response) {
|
||||
Mautic.internalDynamicContentItemCreateListeners = [];
|
||||
Mautic.internalDynamicContentFilterCreateListeners = [];
|
||||
|
||||
if (mQuery('#emailform_plainText').length) {
|
||||
// @todo initiate the token dropdown
|
||||
var plaintext = mQuery('#emailform_plainText');
|
||||
|
||||
Mautic.initAtWho(plaintext, plaintext.attr('data-token-callback'));
|
||||
Mautic.initSelectTheme(mQuery('#emailform_template'));
|
||||
Mautic.initEmailDynamicContent();
|
||||
|
||||
Mautic.prepareVersioning(
|
||||
function (content) {
|
||||
console.log('undo');
|
||||
},
|
||||
function (content) {
|
||||
console.log('redo');
|
||||
}
|
||||
);
|
||||
|
||||
// Open the builder directly when saved from the builder
|
||||
if (response && response.inBuilder) {
|
||||
Mautic.isInBuilder = true;
|
||||
Mautic.launchBuilder('emailform');
|
||||
Mautic.processBuilderErrors(response);
|
||||
}
|
||||
} else if (mQuery(container + ' #list-search').length) {
|
||||
Mautic.activateSearchAutocomplete('list-search', 'email');
|
||||
}
|
||||
|
||||
if (mQuery('table.email-list').length) {
|
||||
var ids = [];
|
||||
mQuery('td.col-stats').each(function () {
|
||||
var id = mQuery(this).attr('data-stats');
|
||||
ids.push(id);
|
||||
});
|
||||
|
||||
// Get all stats numbers in batches of 10
|
||||
while (ids.length > 0) {
|
||||
let batchIds = ids.splice(0, 1);
|
||||
Mautic.ajaxActionRequest(
|
||||
'email:getEmailCountStats',
|
||||
{ids: batchIds},
|
||||
function (response) {
|
||||
if (response.success && response.stats) {
|
||||
for (var i = 0; i < response.stats.length; i++) {
|
||||
var stat = response.stats[i];
|
||||
if (mQuery('#sent-count-' + stat.id).length) {
|
||||
if (stat.pending) {
|
||||
mQuery('#pending-' + stat.id + ' > a').html(stat.pending);
|
||||
mQuery('#pending-' + stat.id).removeClass('hide');
|
||||
}
|
||||
|
||||
if (stat.queued) {
|
||||
mQuery('#queued-' + stat.id + ' > a').html(stat.queued);
|
||||
mQuery('#queued-' + stat.id).removeClass('hide');
|
||||
}
|
||||
|
||||
mQuery('#sent-count-' + stat.id + ' > a').html(stat.sentCount);
|
||||
mQuery('#read-count-' + stat.id + ' > a').html(stat.readCount);
|
||||
mQuery('#read-percent-' + stat.id + ' > a').html(stat.readPercent);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
false,
|
||||
true,
|
||||
"GET"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (mQuery('#emailGraphStats').length) {
|
||||
// Email detail graph - loaded via AJAX not to block loading a whole page
|
||||
var graphUrl = mQuery('#emailGraphStats').attr('data-graph-url');
|
||||
mQuery("#emailGraphStats").load(graphUrl, function () {
|
||||
Mautic.renderCharts();
|
||||
Mautic.initDateRangePicker('#emailGraphStats #daterange_date_from', '#emailGraphStats #daterange_date_to');
|
||||
});
|
||||
}
|
||||
|
||||
var $loadDeliveredElements = mQuery('[data-email-stat-delivered-for]');
|
||||
if ($loadDeliveredElements.length) {
|
||||
$loadDeliveredElements.each(function(i, el) {
|
||||
Mautic.loadEmailDeliveredStat(mQuery(el));
|
||||
});
|
||||
}
|
||||
|
||||
var $loadEmailUsage = mQuery('[data-fetch-email-usages]');
|
||||
if ($loadEmailUsage.length) {
|
||||
$loadEmailUsage.each(function(i, el) {
|
||||
Mautic.loadEmailUsages(mQuery(el));
|
||||
});
|
||||
}
|
||||
|
||||
Mautic.initMailerIsOwnerGlobalCheck();
|
||||
};
|
||||
|
||||
Mautic.emailOnUnload = function(id) {
|
||||
if (id === '#app-content') {
|
||||
delete Mautic.listCompareChart;
|
||||
}
|
||||
|
||||
if (typeof Mautic.ajaxActionXhrQueue !== 'undefined') {
|
||||
delete Mautic.ajaxActionXhrQueue['email:getEmailCountStats'];
|
||||
}
|
||||
};
|
||||
|
||||
Mautic.insertEmailBuilderToken = function(editorId, token) {
|
||||
var editor = Mautic.getEmailBuilderEditorInstances();
|
||||
editor[instance].insertText(token);
|
||||
};
|
||||
|
||||
Mautic.getEmailAbTestWinnerForm = function(abKey) {
|
||||
if (abKey && mQuery(abKey).val() && mQuery(abKey).closest('.form-group').hasClass('has-error')) {
|
||||
mQuery(abKey).closest('.form-group').removeClass('has-error');
|
||||
if (mQuery(abKey).next().hasClass('help-block')) {
|
||||
mQuery(abKey).next().remove();
|
||||
}
|
||||
}
|
||||
|
||||
Mautic.activateLabelLoadingIndicator('emailform_variantSettings_winnerCriteria');
|
||||
var emailId = mQuery('#emailform_sessionId').val();
|
||||
|
||||
var query = "action=email:getAbTestForm&abKey=" + mQuery(abKey).val() + "&emailId=" + emailId;
|
||||
|
||||
mQuery.ajax({
|
||||
url: mauticAjaxUrl,
|
||||
type: "POST",
|
||||
data: query,
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
if (typeof response.html != 'undefined') {
|
||||
if (mQuery('#emailform_variantSettings_properties').length) {
|
||||
mQuery('#emailform_variantSettings_properties').replaceWith(response.html);
|
||||
} else {
|
||||
mQuery('#emailform_variantSettings').append(response.html);
|
||||
}
|
||||
|
||||
if (response.html != '') {
|
||||
Mautic.onPageLoad('#emailform_variantSettings_properties', response);
|
||||
}
|
||||
}
|
||||
},
|
||||
error: function (request, textStatus, errorThrown) {
|
||||
Mautic.processAjaxError(request, textStatus, errorThrown);
|
||||
},
|
||||
complete: function() {
|
||||
Mautic.removeLabelLoadingIndicator();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Mautic.submitSendForm = function () {
|
||||
Mautic.dismissConfirmation();
|
||||
mQuery('.btn-send').prop('disabled', true);
|
||||
mQuery('form[name=\'batch_send\']').submit();
|
||||
};
|
||||
|
||||
Mautic.emailSendOnLoad = function (container, response) {
|
||||
if (mQuery('.email-send-progress').length) {
|
||||
if (!mQuery('#emailSendProgress').length) {
|
||||
Mautic.clearModeratedInterval('emailSendProgress');
|
||||
} else {
|
||||
Mautic.setModeratedInterval('emailSendProgress', 'sendEmailBatch', 2000);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Mautic.emailSendOnUnload = function () {
|
||||
if (mQuery('.email-send-progress').length) {
|
||||
Mautic.clearModeratedInterval('emailSendProgress');
|
||||
if (typeof Mautic.sendEmailBatchXhr != 'undefined') {
|
||||
Mautic.sendEmailBatchXhr.abort();
|
||||
delete Mautic.sendEmailBatchXhr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Mautic.sendEmailBatch = function () {
|
||||
var data = 'id=' + mQuery('.progress-bar-send').data('email') + '&pending=' + mQuery('.progress-bar-send').attr('aria-valuemax') + '&batchlimit=' + mQuery('.progress-bar-send').data('batchlimit');
|
||||
Mautic.sendEmailBatchXhr = Mautic.ajaxActionRequest('email:sendBatch', data, function (response) {
|
||||
if (response.progress) {
|
||||
if (response.progress[0] > 0) {
|
||||
mQuery('.imported-count').html(response.progress[0]);
|
||||
mQuery('.progress-bar-send').attr('aria-valuenow', response.progress[0]).css('width', response.percent + '%');
|
||||
mQuery('.progress-bar-send span.sr-only').html(response.percent + '%');
|
||||
}
|
||||
|
||||
if (response.progress[0] >= response.progress[1]) {
|
||||
Mautic.clearModeratedInterval('emailSendProgress');
|
||||
|
||||
setTimeout(function () {
|
||||
mQuery.ajax({
|
||||
type: 'POST',
|
||||
showLoadingBar: false,
|
||||
url: window.location,
|
||||
data: 'complete=1',
|
||||
success: function (response) {
|
||||
|
||||
if (response.newContent) {
|
||||
// It's done so pass to process page
|
||||
Mautic.processPageContent(response);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
Mautic.moderatedIntervalCallbackIsComplete('emailSendProgress');
|
||||
});
|
||||
};
|
||||
|
||||
Mautic.autoGeneratePlaintext = function() {
|
||||
mQuery('.plaintext-spinner').removeClass('hide');
|
||||
|
||||
Mautic.ajaxActionRequest(
|
||||
'email:generatePlaintText',
|
||||
{
|
||||
id: mQuery('#emailform_sessionId').val(),
|
||||
custom: mQuery('#emailform_customHtml').val()
|
||||
},
|
||||
function (response) {
|
||||
mQuery('#emailform_plainText').val(response.text);
|
||||
mQuery('.plaintext-spinner').addClass('hide');
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
Mautic.selectEmailType = function(emailType) {
|
||||
if (emailType == 'list') {
|
||||
mQuery('#leadList').removeClass('hide');
|
||||
mQuery('#segmentTranslationParent').removeClass('hide');
|
||||
mQuery('#templateTranslationParent').addClass('hide');
|
||||
mQuery('.page-header h3').text(mauticLang.newListEmail);
|
||||
} else {
|
||||
mQuery('#segmentTranslationParent').addClass('hide');
|
||||
mQuery('#templateTranslationParent').removeClass('hide');
|
||||
mQuery('#leadList').addClass('hide');
|
||||
mQuery('.page-header h3').text(mauticLang.newTemplateEmail);
|
||||
}
|
||||
|
||||
mQuery('#emailform_emailType').val(emailType);
|
||||
|
||||
mQuery('body').removeClass('noscroll');
|
||||
|
||||
mQuery('.email-type-modal').remove();
|
||||
mQuery('.email-type-modal-backdrop').remove();
|
||||
};
|
||||
|
||||
Mautic.getTotalAttachmentSize = function() {
|
||||
var assets = mQuery('#emailform_assetAttachments').val();
|
||||
if (assets) {
|
||||
assets = {
|
||||
'assets': assets
|
||||
};
|
||||
Mautic.ajaxActionRequest('email:getAttachmentsSize', assets, function(response) {
|
||||
mQuery('#attachment-size').text(response.size);
|
||||
}, false, false, "GET");
|
||||
} else {
|
||||
mQuery('#attachment-size').text('0');
|
||||
}
|
||||
};
|
||||
|
||||
Mautic.standardEmailUrl = function(options) {
|
||||
if (options && options.windowUrl && options.origin) {
|
||||
var url = options.windowUrl;
|
||||
var editEmailKey = '/emails/edit/emailId';
|
||||
var previewEmailKey = '/email/preview/emailId';
|
||||
if (url.indexOf(editEmailKey) > -1 ||
|
||||
url.indexOf(previewEmailKey) > -1) {
|
||||
options.windowUrl = url.replace('emailId', mQuery(options.origin).val());
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enables/Disables email preview and edit. Can be triggered from campaign or form actions
|
||||
* @param opener
|
||||
* @param origin
|
||||
*/
|
||||
Mautic.disabledEmailAction = function(opener, origin) {
|
||||
if (typeof opener == 'undefined') {
|
||||
opener = window;
|
||||
}
|
||||
var email = opener.mQuery(origin);
|
||||
if (email.length == 0) return;
|
||||
var emailId = email.val();
|
||||
var disabled = emailId === '' || emailId === null;
|
||||
|
||||
opener.mQuery('[id$=_editEmailButton]').prop('disabled', disabled);
|
||||
opener.mQuery('[id$=_previewEmailButton]').prop('disabled', disabled);
|
||||
};
|
||||
|
||||
Mautic.initEmailDynamicContent = function() {
|
||||
if (mQuery('#dynamic-content-container').length) {
|
||||
mQuery('#emailFilters .remove-selected').each( function (index, el) {
|
||||
mQuery(el).on('click', function () {
|
||||
mQuery(this).closest('.panel').animate(
|
||||
{'opacity': 0},
|
||||
'fast',
|
||||
function () {
|
||||
mQuery(this).remove();
|
||||
}
|
||||
);
|
||||
|
||||
if (!mQuery('#emailFilters li:not(.placeholder)').length) {
|
||||
mQuery('#emailFilters li.placeholder').removeClass('hide');
|
||||
} else {
|
||||
mQuery('#emailFilters li.placeholder').addClass('hide');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
mQuery('#addNewDynamicContent').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Mautic.createNewDynamicContentItem();
|
||||
});
|
||||
|
||||
Mautic.initDynamicContentItem();
|
||||
}
|
||||
};
|
||||
|
||||
Mautic.createNewDynamicContentItem = function(jQueryVariant) {
|
||||
// To support the parent.mQuery from the builder
|
||||
var mQuery = (typeof jQueryVariant != 'undefined') ? jQueryVariant : window.mQuery;
|
||||
|
||||
var tabHolder = mQuery('#dynamicContentTabs');
|
||||
var filterHolder = mQuery('#dynamicContentContainer');
|
||||
var dynamicContentPrototype = mQuery('#dynamicContentPrototype').data('prototype');
|
||||
var dynamicContentIndex = tabHolder.find('li').length - 1;
|
||||
while (mQuery('#emailform_dynamicContent_' + dynamicContentIndex).length > 0) {
|
||||
dynamicContentIndex++; // prevent duplicate ids
|
||||
}
|
||||
var tabId = '#emailform_dynamicContent_' + dynamicContentIndex;
|
||||
var tokenName = 'Dynamic Content ' + (dynamicContentIndex + 1);
|
||||
var newForm = dynamicContentPrototype.replace(/__name__/g, dynamicContentIndex);
|
||||
var newTab = mQuery('<li><a role="tab" data-toggle="tab" href="' + tabId + '">' + tokenName + '</a></li>');
|
||||
|
||||
tabHolder.append(newTab);
|
||||
filterHolder.append(newForm);
|
||||
|
||||
var itemContainer = mQuery(tabId);
|
||||
var textarea = itemContainer.find('.editor');
|
||||
var firstInput = itemContainer.find('input[type="text"]').first();
|
||||
|
||||
if (Mautic.internalDynamicContentItemCreateListeners) {
|
||||
Mautic.internalDynamicContentItemCreateListeners.forEach(function(callback) {
|
||||
callback(textarea);
|
||||
});
|
||||
}
|
||||
|
||||
tabHolder.find('i').first().removeClass('ri-loader-3-line ri-spin').addClass('ri-add-line text-success');
|
||||
newTab.find('a').tab('show');
|
||||
|
||||
firstInput.focus();
|
||||
|
||||
Mautic.updateDynamicContentDropdown();
|
||||
|
||||
Mautic.initDynamicContentItem(tabId, mQuery, tokenName);
|
||||
|
||||
return tabId;
|
||||
};
|
||||
|
||||
Mautic.dynamicContentAddNewItemListener = function(callback) {
|
||||
Mautic.internalDynamicContentItemCreateListeners.push(callback);
|
||||
}
|
||||
|
||||
Mautic.createNewDynamicContentFilter = function(el, jQueryVariant) {
|
||||
// To support the parent.mQuery from the builder
|
||||
var mQuery = (typeof jQueryVariant != 'undefined') ? jQueryVariant : window.mQuery;
|
||||
|
||||
var $this = mQuery(el);
|
||||
var parentElement = $this.parents('.panel');
|
||||
var tabHolder = parentElement.find('.nav');
|
||||
var filterHolder = parentElement.find('.tab-content');
|
||||
var filterBlockPrototype = mQuery('#filterBlockPrototype');
|
||||
var filterIndex = filterHolder.find('.tab-pane').length - 1;
|
||||
var dynamicContentIndex = $this.parents('.tab-pane').attr('id').match(/\d+$/)[0];
|
||||
|
||||
var filterPrototype = filterBlockPrototype.data('prototype');
|
||||
var filterContainerId = '#emailform_dynamicContent_' + dynamicContentIndex + '_filters_' + filterIndex ;
|
||||
// prevent duplicate ids
|
||||
while (mQuery(filterContainerId).length > 0) {
|
||||
filterIndex++;
|
||||
filterContainerId = '#emailform_dynamicContent_' + dynamicContentIndex + '_filters_' + filterIndex ;
|
||||
}
|
||||
var newTab = mQuery('<li><a role="tab" data-toggle="tab" href="' + filterContainerId + '">Variation ' + (filterIndex + 1) + '</a></li>');
|
||||
var newForm = filterPrototype.replace(/__name__/g, filterIndex)
|
||||
.replace(/dynamicContent_0_filters/g, 'dynamicContent_' + dynamicContentIndex + '_filters')
|
||||
.replace(/dynamicContent]\[0]\[filters/g, 'dynamicContent][' + dynamicContentIndex + '][filters');
|
||||
|
||||
tabHolder.append(newTab);
|
||||
filterHolder.append(newForm);
|
||||
|
||||
var filterContainer = mQuery(filterContainerId);
|
||||
var availableFilters = filterContainer.find('select[data-mautic="available_filters"]');
|
||||
var altTextarea = filterContainer.find('.editor');
|
||||
var removeButton = filterContainer.find('.remove-item');
|
||||
|
||||
Mautic.activateChosenSelect(availableFilters, false, mQuery);
|
||||
|
||||
availableFilters.on('change', function() {
|
||||
var $this = mQuery(this);
|
||||
|
||||
if ($this.val()) {
|
||||
Mautic.addDynamicContentFilter($this.val(), mQuery);
|
||||
$this.val('');
|
||||
$this.trigger('chosen:updated');
|
||||
}
|
||||
});
|
||||
|
||||
if (Mautic.internalDynamicContentFilterCreateListeners) {
|
||||
Mautic.internalDynamicContentFilterCreateListeners.forEach(function(callback) {
|
||||
callback(altTextarea);
|
||||
});
|
||||
}
|
||||
|
||||
Mautic.initRemoveEvents(removeButton, mQuery);
|
||||
|
||||
newTab.find('a').tab('show');
|
||||
|
||||
return filterContainerId;
|
||||
};
|
||||
|
||||
Mautic.dynamicContentAddNewFilterListener = function(callback) {
|
||||
Mautic.internalDynamicContentFilterCreateListeners.push(callback);
|
||||
}
|
||||
|
||||
Mautic.initDynamicContentItem = function (tabId, jQueryVariant, tokenName) {
|
||||
// To support the parent.mQuery from the builder
|
||||
var mQuery = (typeof jQueryVariant != 'undefined') ? jQueryVariant : window.mQuery;
|
||||
|
||||
var $el = mQuery('#dynamic-content-container');
|
||||
if ($el.length === 0){
|
||||
mQuery = parent.mQuery;
|
||||
$el = mQuery('#dynamic-content-container');
|
||||
}
|
||||
|
||||
if (tabId || typeof tabId != "undefined") {
|
||||
$el = mQuery(tabId);
|
||||
}
|
||||
|
||||
// add a click event listener for adding a new dynamic content variant
|
||||
$el.find('.addNewDynamicContentFilter').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Mautic.createNewDynamicContentFilter(this);
|
||||
});
|
||||
|
||||
if (typeof tokenName != 'undefined') {
|
||||
$el.find('.dynamic-content-token-name').val(tokenName);
|
||||
}
|
||||
|
||||
if ($el.find('.dynamic-content-token-name').val() === '') {
|
||||
var dynamicContent = $el.attr('id').match(/\d+$/);
|
||||
if (dynamicContent) {
|
||||
var dynamicContentIndex = dynamicContent[0];
|
||||
$el.find('.dynamic-content-token-name').val('Dynamic Content ' + dynamicContentIndex);
|
||||
}
|
||||
}
|
||||
|
||||
$el.find('a.remove-selected').on('click', function() {
|
||||
mQuery(this).closest('.panel').animate(
|
||||
{'opacity': 0},
|
||||
'fast',
|
||||
function () {
|
||||
mQuery(this).remove();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$el.find('select[data-mautic="available_filters"]').on('change', function() {
|
||||
var $this = mQuery(this);
|
||||
|
||||
if ($this.val()) {
|
||||
Mautic.addDynamicContentFilter($this.val(), mQuery);
|
||||
$this.val('');
|
||||
$this.trigger('chosen:updated');
|
||||
}
|
||||
});
|
||||
|
||||
Mautic.initRemoveEvents($el.find('.remove-item'), mQuery);
|
||||
};
|
||||
|
||||
Mautic.updateDynamicContentDropdown = function () {
|
||||
var options = [];
|
||||
|
||||
mQuery('#dynamicContentTabs').find('a[data-toggle="tab"]').each(function () {
|
||||
var prototype = '<li><a class="fr-command" data-cmd="dynamicContent" data-param1="__tokenName__">__tokenName__</a></li>';
|
||||
var newOption = prototype.replace(/__tokenName__/g, mQuery(this).text());
|
||||
|
||||
options.push(newOption);
|
||||
});
|
||||
|
||||
mQuery('button[data-cmd="dynamicContent"]').next().find('ul').html(options.join(''));
|
||||
};
|
||||
|
||||
Mautic.initMailerIsOwnerGlobalCheck = function() {
|
||||
let radioSelector = '.mailer-is-owner-local';
|
||||
Mautic.toggleMailerIsOwnerWarningMessage(radioSelector);
|
||||
mQuery(radioSelector).on('change', function() {
|
||||
Mautic.toggleMailerIsOwnerWarningMessage(radioSelector);
|
||||
});
|
||||
}
|
||||
|
||||
Mautic.toggleMailerIsOwnerWarningMessage = function(radioSelector) {
|
||||
let checkedRadio = mQuery(radioSelector+':checked');
|
||||
let globalMailerIsOwnerValue = checkedRadio.attr('data-global-mailer-is-onwer') ? '1' : '0';
|
||||
let warningMessageId = 'mailer-is-owner-waring';
|
||||
|
||||
mQuery('#'+warningMessageId).remove();
|
||||
|
||||
if (checkedRadio.val() !== globalMailerIsOwnerValue) {
|
||||
let warning = mQuery('<div/>');
|
||||
warning.attr('id', warningMessageId);
|
||||
warning.html(checkedRadio.attr('data-warning'));
|
||||
warning.addClass('alert alert-warning mt-md');
|
||||
checkedRadio.closest('.form-group').append(warning);
|
||||
}
|
||||
}
|
||||
|
||||
Mautic.initRemoveEvents = function (elements, jQueryVariant) {
|
||||
var mQuery = (typeof jQueryVariant != 'undefined') ? jQueryVariant : window.mQuery;
|
||||
if (elements.hasClass('remove-selected')) {
|
||||
elements.on('click', function() {
|
||||
mQuery(this).closest('.panel').animate(
|
||||
{'opacity': 0},
|
||||
'fast',
|
||||
function () {
|
||||
mQuery(this).remove();
|
||||
}
|
||||
);
|
||||
});
|
||||
} else {
|
||||
elements.on('click', function (e) {
|
||||
e.preventDefault();
|
||||
var $this = mQuery(this);
|
||||
var parentElement = $this.parents('.tab-pane.dynamic-content');
|
||||
|
||||
if ($this.hasClass('remove-filter')) {
|
||||
parentElement = $this.parents('.tab-pane.dynamic-content-filter');
|
||||
}
|
||||
|
||||
var tabLink = mQuery('a[href="#' + parentElement.attr('id') + '"]').parent();
|
||||
var tabContainer = tabLink.parent();
|
||||
|
||||
parentElement.remove();
|
||||
tabLink.remove();
|
||||
// if tabContainer is for variants, show the first one, if it is the DEC vertical list, show the second one
|
||||
if (tabContainer.hasClass('tabs-left') || $this.hasClass('remove-filter')) {
|
||||
tabContainer.find('li').first().next().find('a').tab('show');
|
||||
} else {
|
||||
tabContainer.find('li').first().find('a').tab('show');
|
||||
}
|
||||
|
||||
Mautic.updateDynamicContentDropdown();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Mautic.addDynamicContentFilter = function (selectedFilter, jQueryVariant) {
|
||||
var mQuery = (typeof jQueryVariant != 'undefined') ? jQueryVariant : window.mQuery;
|
||||
|
||||
var dynamicContentItems = mQuery('.tab-pane.dynamic-content');
|
||||
var activeDynamicContent = dynamicContentItems.filter(':visible');
|
||||
var dynamicContentIndex = activeDynamicContent.attr('id').match(/\d+$/)[0]; //dynamicContentItems.index(activeDynamicContent);
|
||||
|
||||
var dynamicContentFilterContainers = activeDynamicContent.find('div[data-filter-container]');
|
||||
var activeDynamicContentFilterContainer = dynamicContentFilterContainers.filter(':visible');
|
||||
var dynamicContentFilterIndex = dynamicContentFilterContainers.index(activeDynamicContentFilterContainer);
|
||||
|
||||
var selectedOption = mQuery('option[data-mautic="available_' + selectedFilter + '"]').first();
|
||||
var label = selectedOption.text();
|
||||
|
||||
// create a new filter
|
||||
var filterNum = activeDynamicContentFilterContainer.children('.panel').length;
|
||||
var prototype = mQuery('#filterSelectPrototype').data('prototype');
|
||||
var fieldObject = selectedOption.data('field-object');
|
||||
var fieldType = selectedOption.data('field-type');
|
||||
var isSpecial = (mQuery.inArray(fieldType, ['leadlist', 'assets', 'lead_email_received', 'tags', 'multiselect', 'boolean', 'select', 'country', 'timezone', 'region', 'stage', 'locale']) != -1);
|
||||
|
||||
// Update the prototype settings
|
||||
prototype = prototype.replace(/__name__/g, filterNum)
|
||||
.replace(/__label__/g, label)
|
||||
.replace(/dynamicContent_0_filters/g, 'dynamicContent_' + dynamicContentIndex + '_filters')
|
||||
.replace(/dynamicContent]\[0]\[filters/g, 'dynamicContent][' + dynamicContentIndex + '][filters')
|
||||
.replace(/filters_0_filters/g, 'filters_' + dynamicContentFilterIndex + '_filters')
|
||||
.replace(/filters]\[0]\[filters/g, 'filters][' + dynamicContentFilterIndex + '][filters');
|
||||
|
||||
if (filterNum === 0) {
|
||||
prototype = prototype.replace(/in-group/g, '');
|
||||
}
|
||||
|
||||
// Convert to DOM
|
||||
prototype = mQuery(prototype);
|
||||
|
||||
if (fieldObject == 'company') {
|
||||
prototype.find('.object-icon').removeClass('ri-user-6-fill').addClass('ri-building-2-line');
|
||||
} else {
|
||||
prototype.find('.object-icon').removeClass('ri-building-2-line').addClass('ri-user-6-fill');
|
||||
}
|
||||
|
||||
var filterBase = "emailform[dynamicContent][" + dynamicContentIndex + "][filters][" + dynamicContentFilterIndex + "][filters][" + filterNum + "]";
|
||||
var filterIdBase = "emailform_dynamicContent_" + dynamicContentIndex + "_filters_" + dynamicContentFilterIndex + "_filters_" + filterNum;
|
||||
|
||||
if (isSpecial) {
|
||||
var templateField = fieldType;
|
||||
if (fieldType == 'boolean' || fieldType == 'multiselect' || fieldType == 'leadlist') {
|
||||
templateField = 'select';
|
||||
}
|
||||
var template = mQuery('#templates .' + templateField + '-template').clone();
|
||||
var $template = mQuery(template);
|
||||
var templateNameAttr = $template.attr('name').replace(/__name__/g, filterNum)
|
||||
.replace(/__dynamicContentIndex__/g, dynamicContentIndex)
|
||||
.replace(/__dynamicContentFilterIndex__/g, dynamicContentFilterIndex);
|
||||
var templateIdAttr = $template.attr('id').replace(/__name__/g, filterNum)
|
||||
.replace(/__dynamicContentIndex__/g, dynamicContentIndex)
|
||||
.replace(/__dynamicContentFilterIndex__/g, dynamicContentFilterIndex);
|
||||
|
||||
$template.attr('name', templateNameAttr);
|
||||
$template.attr('id', templateIdAttr);
|
||||
|
||||
prototype.find('input[name="' + filterBase + '[filter]"]').replaceWith(template);
|
||||
}
|
||||
|
||||
if (activeDynamicContentFilterContainer.find('.panel').length == 0) {
|
||||
// First filter so hide the glue footer
|
||||
prototype.find(".panel-footer").addClass('hide');
|
||||
}
|
||||
|
||||
prototype.find("input[name='" + filterBase + "[field]']").val(selectedFilter);
|
||||
prototype.find("input[name='" + filterBase + "[type]']").val(fieldType);
|
||||
prototype.find("input[name='" + filterBase + "[object]']").val(fieldObject);
|
||||
|
||||
var filterEl = (isSpecial) ? "select[name='" + filterBase + "[filter]']" : "input[name='" + filterBase + "[filter]']";
|
||||
|
||||
activeDynamicContentFilterContainer.append(prototype);
|
||||
|
||||
Mautic.initRemoveEvents(activeDynamicContentFilterContainer.find("a.remove-selected"), mQuery);
|
||||
|
||||
var filter = '#' + filterIdBase + '_filter';
|
||||
|
||||
var fieldOptions = fieldCallback = '';
|
||||
//activate fields
|
||||
if (isSpecial) {
|
||||
if (fieldType == 'select' || fieldType == 'boolean' || fieldType == 'multiselect' || fieldType == 'leadlist') {
|
||||
// Generate the options
|
||||
fieldOptions = selectedOption.data("field-list");
|
||||
|
||||
mQuery.each(fieldOptions, function(index, val) {
|
||||
mQuery('<option>').val(index).text(val).appendTo(filterEl);
|
||||
});
|
||||
}
|
||||
} else if (fieldType == 'lookup') {
|
||||
fieldCallback = selectedOption.data("field-callback");
|
||||
if (fieldCallback && typeof Mautic[fieldCallback] == 'function') {
|
||||
fieldOptions = selectedOption.data("field-list");
|
||||
Mautic[fieldCallback](filterIdBase + '_filter', selectedFilter, fieldOptions);
|
||||
}
|
||||
} else if (fieldType == 'datetime') {
|
||||
mQuery(filter).datetimepicker({
|
||||
format: 'Y-m-d H:i',
|
||||
lazyInit: true,
|
||||
validateOnBlur: false,
|
||||
allowBlank: true,
|
||||
scrollMonth: false,
|
||||
scrollInput: false
|
||||
});
|
||||
} else if (fieldType == 'date') {
|
||||
mQuery(filter).datetimepicker({
|
||||
timepicker: false,
|
||||
format: 'Y-m-d',
|
||||
lazyInit: true,
|
||||
validateOnBlur: false,
|
||||
allowBlank: true,
|
||||
scrollMonth: false,
|
||||
scrollInput: false,
|
||||
closeOnDateSelect: true
|
||||
});
|
||||
} else if (fieldType == 'time') {
|
||||
mQuery(filter).datetimepicker({
|
||||
datepicker: false,
|
||||
format: 'H:i',
|
||||
lazyInit: true,
|
||||
validateOnBlur: false,
|
||||
allowBlank: true,
|
||||
scrollMonth: false,
|
||||
scrollInput: false
|
||||
});
|
||||
} else if (fieldType == 'lookup_id') {
|
||||
//switch the filter and display elements
|
||||
var oldFilter = mQuery(filterEl);
|
||||
var newDisplay = mQuery(oldFilter).clone();
|
||||
mQuery(newDisplay).attr('name', filterBase + '[display]')
|
||||
.attr('id', filterIdBase + '_display');
|
||||
|
||||
var oldDisplay = mQuery(prototype).find("input[name='" + filterBase + "[display]']");
|
||||
var newFilter = mQuery(oldDisplay).clone();
|
||||
mQuery(newFilter).attr('name', filterBase + '[filter]')
|
||||
.attr('id', filterIdBase + '_filter');
|
||||
|
||||
mQuery(oldFilter).replaceWith(newFilter);
|
||||
mQuery(oldDisplay).replaceWith(newDisplay);
|
||||
|
||||
var fieldCallback = selectedOption.data("field-callback");
|
||||
if (fieldCallback && typeof Mautic[fieldCallback] == 'function') {
|
||||
fieldOptions = selectedOption.data("field-list");
|
||||
Mautic[fieldCallback](filterIdBase + '_display', selectedFilter, fieldOptions, mQuery);
|
||||
}
|
||||
} else {
|
||||
mQuery(filter).attr('type', fieldType);
|
||||
}
|
||||
|
||||
var operators = mQuery(selectedOption).data('field-operators');
|
||||
mQuery('#' + filterIdBase + '_operator').html('');
|
||||
mQuery.each(operators, function (label, value) {
|
||||
var newOption = mQuery('<option/>').val(value).text(label);
|
||||
newOption.appendTo(mQuery('#' + filterIdBase + '_operator'));
|
||||
});
|
||||
|
||||
// Convert based on first option in list
|
||||
Mautic.convertDwcFilterInput('#' + filterIdBase + '_operator', mQuery);
|
||||
};
|
||||
|
||||
Mautic.copySubjectToName = function(elemSubject) {
|
||||
let elemName = mQuery("#emailform_name");
|
||||
if (elemName.val() === "") {
|
||||
elemName.val(elemSubject.val());
|
||||
}
|
||||
};
|
||||
|
||||
Mautic.loadEmailDeliveredStat = function($el) {
|
||||
var emailId = $el.data('email-stat-delivered-for');
|
||||
Mautic.ajaxActionRequest('email:getEmailDeliveredCount', {id: emailId}, function(response){
|
||||
if (response.success) {
|
||||
var delivered = response.delivered;
|
||||
$el.html(delivered);
|
||||
}
|
||||
}, false, true, "GET");
|
||||
};
|
||||
|
||||
Mautic.loadEmailUsages = function($el) {
|
||||
var emailId = $el.data('fetch-email-usages');
|
||||
Mautic.ajaxActionRequest('email:getEmailUsages', {id: emailId}, function(response){
|
||||
var usagesHtml = response.usagesHtml;
|
||||
$el.html(usagesHtml);
|
||||
}, false, true, "GET");
|
||||
};
|
||||
@@ -0,0 +1,255 @@
|
||||
(function(window, document, Mautic, $, Math) {
|
||||
class Heatmap {
|
||||
constructor(emailId) {
|
||||
this.emailId = emailId;
|
||||
this.mode = 'total';
|
||||
this.content = null;
|
||||
this.clickStats = null;
|
||||
this.$modal = null;
|
||||
this.$iframe = null;
|
||||
this.$iframeBody = null;
|
||||
this.iframeDocument = null;
|
||||
this.totalClicks = null;
|
||||
this.totalUniqueClicks = null;
|
||||
this.legendTemplate = null;
|
||||
this.links = [];
|
||||
this.gradient = [
|
||||
[44, 59, 182], // #2c3bb6
|
||||
[10, 133, 255], // #0a85ff
|
||||
[240, 223, 66], // #f0df42
|
||||
[248, 195, 68], // #f8c344
|
||||
[255, 132, 58], // #ff843a
|
||||
[248, 56, 52] // #f83834
|
||||
];
|
||||
}
|
||||
|
||||
init() {
|
||||
this.fetchHeatmap(function() {
|
||||
this.render();
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
render() {
|
||||
this.renderModal();
|
||||
this.bindEvents();
|
||||
this.$modal.modal('show');
|
||||
}
|
||||
|
||||
fetchHeatmap(callback) {
|
||||
Mautic.ajaxActionRequest('email:heatmap', {id: this.emailId}, function(response){
|
||||
this.content = response.content;
|
||||
this.clickStats = response.clickStats;
|
||||
this.totalClicks = response.totalClicks;
|
||||
this.totalUniqueClicks = response.totalUniqueClicks;
|
||||
this.legendTemplate = response.legendTemplate;
|
||||
callback();
|
||||
}.bind(this), false, true, "GET");
|
||||
}
|
||||
|
||||
waitForIframeContent(callback) {
|
||||
const self = this;
|
||||
const interval = setInterval(function () {
|
||||
const height = self.$iframeBody.height();
|
||||
if (height > 0 && self.lastHeight === height) {
|
||||
callback();
|
||||
clearInterval(interval);
|
||||
} else {
|
||||
self.lastHeight = height;
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
const self = this;
|
||||
|
||||
self.$iframe[0].addEventListener('load', function() {
|
||||
self.waitForIframeContent(function() {
|
||||
self.renderLabels();
|
||||
self.bindMouseEvents();
|
||||
});
|
||||
});
|
||||
|
||||
$(window).on('resize', function() {
|
||||
self.labelPositions();
|
||||
});
|
||||
|
||||
self.$modal.on('hidden.bs.modal', function () {
|
||||
$(this).remove();
|
||||
});
|
||||
|
||||
$('[data-toggle="heatmap-total"]').click(function(e) {
|
||||
e.preventDefault();
|
||||
if (self.mode === 'total') return;
|
||||
self.mode = 'total';
|
||||
$('[data-heatmap-clicks]').html(self.totalClicks);
|
||||
$('[data-toggle="heatmap-unique"]').removeClass('active');
|
||||
$(this).addClass('active');
|
||||
self.removeLabels();
|
||||
self.renderLabels();
|
||||
});
|
||||
|
||||
$('[data-toggle="heatmap-unique"]').click(function(e) {
|
||||
e.preventDefault();
|
||||
if (self.mode === 'unique') return;
|
||||
self.mode = 'unique';
|
||||
$('[data-heatmap-clicks]').html(self.totalUniqueClicks);
|
||||
$('[data-toggle="heatmap-total"]').removeClass('active');
|
||||
$(this).addClass('active');
|
||||
self.removeLabels();
|
||||
self.renderLabels();
|
||||
});
|
||||
|
||||
$('div.heatmap-legend').on('scroll mousewheel touchmove', function(e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
}
|
||||
|
||||
bindMouseEvents() {
|
||||
const self = this;
|
||||
|
||||
const moveUp = function() {
|
||||
const $label = $(this).hasClass('heatmap-link') ? $(this).data('heatmap-label') : $(this);
|
||||
$label.css('z-index', 2050);
|
||||
}
|
||||
const moveDown = function() {
|
||||
const $label = $(this).hasClass('heatmap-link') ? $(this).data('heatmap-label') : $(this);
|
||||
$label.css('z-index', 1050);
|
||||
}
|
||||
|
||||
self.$iframeBody.on('mouseenter focus', '.heatmap-label, a.heatmap-link', moveUp);
|
||||
self.$iframeBody.on('mouseleave blur', '.heatmap-label, a.heatmap-link', moveDown);
|
||||
}
|
||||
|
||||
renderModal() {
|
||||
this.$modal = $("<div />").attr({"class": "modal fade heatmap-modal"});
|
||||
const $modalDialogDiv = $("<div />").attr({"class": "modal-dialog modal-dialog-heatmap"});
|
||||
const $modalContentDiv = $("<div />").attr({"class": "modal-content"});
|
||||
this.$iframe = $('<iframe class="heatmap-iframe">' + this.content + '</iframe>');
|
||||
$modalContentDiv.append(this.$iframe);
|
||||
|
||||
this.$modal.append($modalDialogDiv.append($modalContentDiv));
|
||||
$('body').append(this.$modal);
|
||||
|
||||
this.iframeDocument = this.$iframe[0].contentDocument || this.$iframe[0].contentWindow.document;
|
||||
this.iframeDocument.open();
|
||||
this.iframeDocument.write(this.content);
|
||||
|
||||
const cssLink = document.createElement("link");
|
||||
cssLink.href = "/app/bundles/EmailBundle/Assets/css/heatmap.css";
|
||||
cssLink.rel = "stylesheet";
|
||||
cssLink.type = "text/css";
|
||||
this.iframeDocument.head.appendChild(cssLink);
|
||||
|
||||
this.$iframeBody = $('body', this.iframeDocument);
|
||||
this.$iframeBody.addClass('heatmap-iframe-body');
|
||||
$modalContentDiv.append(this.legendTemplate);
|
||||
$modalContentDiv.append('<button type="button" class="modal-heatmap-close close" data-dismiss="modal"><span aria-hidden="true">×</span></button>');
|
||||
this.iframeDocument.close();
|
||||
}
|
||||
|
||||
renderLabels() {
|
||||
const self = this;
|
||||
self.clickStats.forEach(function(link) {
|
||||
const $a = $('a[href="' + link.url + '"]', self.$iframeBody);
|
||||
$a.addClass('heatmap-link');
|
||||
$a.each(function() {
|
||||
const $el = $(this);
|
||||
self.links.push($el);
|
||||
|
||||
const rate = self.mode === 'total' ? link.hits_rate : link.unique_hits_rate;
|
||||
const percent = Math.round(rate * 100);
|
||||
const text = (self.mode === 'total' ? link.hits_text : link.unique_hits_text) + ' (' + percent.toString() + '%)';
|
||||
|
||||
const $label = $('<div class="heatmap-label"><p>' + text + '</p></div>');
|
||||
const bgColor = self.interpolateColor(rate);
|
||||
const bgColorLeft = self.interpolateColor(rate - 0.1);
|
||||
const bgColorRight = self.interpolateColor(rate + 0.1);
|
||||
$label.css({
|
||||
'background-color': bgColor,
|
||||
'background': 'linear-gradient(to right, ' +bgColorLeft+ ', '+ bgColorRight +')'
|
||||
});
|
||||
const $border = $('<div class="heatmap-label-border"></div>');
|
||||
$border.css({
|
||||
'border': '1px dashed ' + bgColor,
|
||||
'border-bottom': 'none'
|
||||
});
|
||||
$label.append($border);
|
||||
$label.attr('title', link.url);
|
||||
|
||||
self.$iframeBody.append($label);
|
||||
$el.data('heatmap-label', $label);
|
||||
$el.data('heatmap-label-border', $border);
|
||||
$label.data('a', $a);
|
||||
});
|
||||
});
|
||||
self.labelPositions();
|
||||
}
|
||||
|
||||
removeLabels() {
|
||||
if (!this.links.length) return;
|
||||
|
||||
$(this.links).each(function() {
|
||||
$(this).data('heatmap-label').remove();
|
||||
});
|
||||
this.links = [];
|
||||
}
|
||||
|
||||
labelPositions() {
|
||||
const self = this;
|
||||
|
||||
$(self.links).each(function() {
|
||||
const $el = $(this);
|
||||
const $label = $el.data('heatmap-label');
|
||||
const $border = $el.data('heatmap-label-border');
|
||||
const position = $el.position();
|
||||
$label.css({
|
||||
position: 'absolute',
|
||||
top: position.top + $el.outerHeight(),
|
||||
left: position.left - 1,
|
||||
'min-width': Math.max($el.outerWidth(), 60) + 2
|
||||
});
|
||||
$border.css({
|
||||
position: 'absolute',
|
||||
bottom: '100%',
|
||||
left: 0,
|
||||
width: $el.outerWidth(),
|
||||
height: $el.outerHeight()
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
interpolateColor(rate) {
|
||||
if (rate <= 0) {
|
||||
return 'rgb(' + this.gradient[0].join(',') + ')';
|
||||
}
|
||||
if (rate >= 1) {
|
||||
const lastIndex = this.gradient.length - 1;
|
||||
return 'rgb(' + this.gradient[lastIndex].join(',') + ')';
|
||||
}
|
||||
|
||||
const segmentCount = this.gradient.length - 1;
|
||||
const segmentWidth = 1 / segmentCount;
|
||||
const segmentIndex = Math.floor(rate / segmentWidth);
|
||||
const segmentPercent = (rate - segmentIndex * segmentWidth) / segmentWidth;
|
||||
|
||||
const color1 = this.gradient[segmentIndex];
|
||||
const color2 = this.gradient[segmentIndex + 1];
|
||||
|
||||
const r = Math.round(color1[0] + (color2[0] - color1[0]) * segmentPercent);
|
||||
const g = Math.round(color1[1] + (color2[1] - color1[1]) * segmentPercent);
|
||||
const b = Math.round(color1[2] + (color2[2] - color1[2]) * segmentPercent);
|
||||
|
||||
return 'rgb(' + r + ',' + g + ',' + b + ')';
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$('body').on('click', '[data-toggle="email-heatmap"]', function(e) {
|
||||
const emailId = $(this).data('email');
|
||||
const heatmap = new Heatmap(emailId);
|
||||
heatmap.init();
|
||||
e.preventDefault();
|
||||
});
|
||||
});
|
||||
|
||||
})(window, document, Mautic, mQuery, Math);
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Used in data-lookup-callback attr of form field in ExampleSendType
|
||||
* Take a look at https://github.com/twitter/typeahead.js/
|
||||
*/
|
||||
Mautic.activateExampleContactLookupField = function(fieldOptions, filterId) {
|
||||
|
||||
const lookupElementId = 'example_send_contact';
|
||||
const action = mQuery('#'+ lookupElementId).attr('data-chosen-lookup');
|
||||
|
||||
const options = {
|
||||
limit: 20,
|
||||
'searchKey': 'lead.lead',
|
||||
};
|
||||
|
||||
Mautic.activateFieldTypeahead(lookupElementId, filterId, options, action);
|
||||
|
||||
mQuery('#'+ lookupElementId).on("change",function(event) {
|
||||
if (event.target.value === '') {
|
||||
// Delete selected contact ID from hidden field
|
||||
mQuery('#example_send_contact_id').val('');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Used in data-lookup-callback attr of form field in ExampleSendType
|
||||
*/
|
||||
Mautic.updateExampleContactLookupListFilter = function(field, item) {
|
||||
if (item && item.id) {
|
||||
mQuery('#example_send_contact_id').val(item.id);
|
||||
mQuery(field).val(item.value);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user