//CampaignBundle /** * Setup the campaign view * * @param container */ Mautic.campaignOnLoad = function (container, response) { Mautic.lazyLoadContactListOnCampaignDetail(); if (mQuery(container + ' #list-search').length) { Mautic.activateSearchAutocomplete('list-search', 'campaign'); } if (mQuery('#CampaignEventPanel').length) { var tooltipTimeout = null; // setup button clicks mQuery('#CampaignEventPanelGroups button').on('click', function() { var eventType = mQuery(this).data('type'); Mautic.campaignBuilderUpdateEventList([eventType], false, 'lists', true); }); mQuery('#CampaignEventPanelLists button').on('click', function() { Mautic.campaignBuilderUpdateEventList(Mautic.campaignBuilderAnchorClickedAllowedEvents, true, 'groups', true); }); // set hover and double click functions for the event buttons if (!(mQuery('.preview').length)) { mQuery('#CampaignCanvas .list-campaign-event, #CampaignCanvas .list-campaign-source').off('.eventbuttons') .on('mouseover.eventbuttons', function() { mQuery(this).find('.campaign-event-buttons').removeClass('hide'); }) .on('mouseout.eventbuttons', function() { mQuery(this).find('.campaign-event-buttons').addClass('hide'); }) .on('dblclick.eventbuttons', function(event) { event.preventDefault(); mQuery(this).find('.btn-edit').first().click(); }); } else { mQuery("#CampaignCanvas div.list-campaign-event").each(function () { var thisId = mQuery(this).attr('id'); var option = mQuery('#'+thisId+' option[value="' + mQuery(this).val() + '"]'); }); } // setup chosen mQuery('.campaign-event-selector').on('chosen:showing_dropdown', function (event) { // Disable canvas scrolling mQuery('.builder-content').css('overflow', 'hidden'); var thisSelect = mQuery(event.target).attr('id'); Mautic.campaignBuilderUpdateEventListTooltips(thisSelect, false); mQuery('#'+thisSelect+'_chosen .chosen-search input').on('keydown.tooltip', function () { // Destroy tooltips that are filtered out Mautic.campaignBuilderUpdateEventListTooltips(thisSelect, true); }).on('keyup.tooltip', function() { // Recreate tooltips for those left if (tooltipTimeout) { clearTimeout(tooltipTimeout); } // wrap into setTimeout for fast typing users. tooltipTimeout = setTimeout(function () { Mautic.campaignBuilderUpdateEventListTooltips(thisSelect, false); }, 200); }); }); mQuery('.campaign-event-selector').on('chosen:hiding_dropdown', function (event) { // Re-enable canvas scrolling mQuery('.builder-content').css('overflow', 'auto'); var thisSelect = mQuery(event.target).attr('id'); Mautic.campaignBuilderUpdateEventListTooltips(thisSelect, true); mQuery('#'+thisSelect+'_chosen .chosen-search input').off('keyup.tooltip') .off('keydown.tooltip'); }); mQuery('.campaign-event-selector').on('change', function() { // Hide events list if (!mQuery('#CampaignEvent_newsource').length) { Mautic.hideCampaignEventPanel(); } // Get the option clicked var thisId = mQuery(this).attr('id'); var option = mQuery('#'+thisId+' option[value="' + mQuery(this).val() + '"]'); if (option.attr('data-href') && Mautic.campaignBuilderAnchorNameClicked) { var updatedUrl = option.attr('data-href').replace(/anchor=(.*?)$/, "anchor=" + Mautic.campaignBuilderAnchorNameClicked + "&anchorEventType=" + Mautic.campaignBuilderAnchorEventTypeClicked); // Replace the anchor in the URL with that clicked option.attr('data-href', updatedUrl); } // Deactivate chosen to kill tooltips mQuery('#'+thisId).trigger('chosen:close'); // Display the modal with form Mautic.ajaxifyModal(option); // Reset the dropdown mQuery(this).val(''); mQuery(this).trigger('chosen:updated'); }); mQuery('#CampaignCanvas').on('click', function(event) { if (!mQuery(event.target).parents('#CampaignCanvas').length && !mQuery('#CampaignEvent_newsource').length) { Mautic.hideCampaignEventPanel(); } }); const $flashes = mQuery('#flashes'); const $builder = mQuery('#campaign-builder'); $builder.on('campaign-builder:show', function () { $builder.addClass('builder-active').removeClass('hide'); $flashes.addClass('alert-offset'); }); $builder.on('campaign-builder:hide', function () { $builder.addClass('hide').removeClass('builder-active'); $flashes.removeClass('alert-offset'); }); Mautic.prepareCampaignCanvas(); // Open the builder directly when saved from the builder if (response && response.inBuilder) { Mautic.launchCampaignEditor(); Mautic.processBuilderErrors(response); } // update the cloned event info when storage is updated from different tab window.addEventListener('storage', function(event) { if (event.key === 'mautic_campaign_event_clone') { Mautic.campaignBuilderUpdateEventCloneDescription(); } }); mQuery(document).ajaxError(function(event, jqxhr, settings, thrownError) { var path = settings.url.split('?')[0]; if (path === "/s/campaigns/events/insert") { Mautic.campaignEventInsertOnError(event, jqxhr); } }); } }; Mautic.lazyLoadContactListOnCampaignDetail = function() { let containerId = '#leads-container'; let container = mQuery(containerId); // Load the contacts only if the container exists. if (!container.length) { return; } let campaignContactUrl = container.data('target-url'); mQuery.get(campaignContactUrl, function(response) { response.target = containerId; Mautic.processPageContent(response); }); }; /** * Update chosen tooltips * * @param theSelect * @param onlyDestroy */ Mautic.campaignBuilderUpdateEventListTooltips = function(theSelect, onlyDestroy) { const $select = mQuery('#'+theSelect); const dataAttribute = 'tooltips'; // create a stack if (undefined === $select.data(dataAttribute)) { $select.data(dataAttribute, []); } // remove existing tooltips before we create new ones. const tooltips = $select.data(dataAttribute); mQuery.each(tooltips, function (index, $tooltip) { if (undefined === $tooltip) { return; } $tooltip.tooltip('hide'); $tooltip.tooltip('destroy'); }); $select.data(dataAttribute, []); if (true === onlyDestroy) { return; } // create tooltips. $select.find('option').each(function () { if (mQuery(this).attr('id')) { // Initiate a tooltip on each option since chosen doesn't copy over the data attributes const chosenOption = '#' + theSelect + '_chosen .option_' + mQuery(this).attr('id'); const $tooltip = mQuery(chosenOption).tooltip({html: true, container: 'body', placement: 'left'}); $select.data(dataAttribute).push($tooltip); } }); } /** * Delete the builder instance so it's regenerated when reopening the campaign event builder */ Mautic.campaignOnUnload = function(container) { delete Mautic.campaignBuilderInstance; delete Mautic.campaignBuilderLabels; } Mautic.campaignEventCloneOnLoad = function(container, response) { Mautic.setCampaignEventClone({ 'sourceEventName': response['eventName'], 'sourceEventType': response['eventType'], 'sourceType': response['type'], 'sourceCampaignId': response['campaignId'], 'sourceCampaignName': response['campaignName'], }); const flashMessage = Mautic.addInfoFlashMessage(Mautic.translate('mautic.campaign.event.clone.success')); Mautic.setFlashes(flashMessage); Mautic.campaignBuilderUpdateEventCloneDescription(); }; Mautic.campaignEventInsertOnError = function (event, jqxhr) { Mautic.clearCampaignEventClone(); Mautic.hideCampaignEventPanel(); if (jqxhr.responseJSON.error) { const flashMessage = Mautic.addErrorFlashMessage(jqxhr.responseJSON.error); Mautic.setFlashes(flashMessage); } }; /** * Setup the campaign event view * * @param container * @param response */ Mautic.campaignEventOnLoad = function (container, response) { if (mQuery('#campaignevent_triggerHour').length) { Mautic.campaignEventUpdateIntervalHours(); mQuery('#campaignevent_triggerHour').on('change', Mautic.campaignEventUpdateIntervalHours); mQuery('#campaignevent_triggerRestrictedStartHour').on('change', Mautic.campaignEventUpdateIntervalHours); mQuery('#campaignevent_triggerRestrictedStopHour').on('change', Mautic.campaignEventUpdateIntervalHours); mQuery('#campaignevent_triggerRestrictedDaysOfWeek_0').on('change', Mautic.campaignEventSelectDOW); mQuery('#campaignevent_triggerRestrictedDaysOfWeek_1').on('change', Mautic.campaignEventSelectDOW); mQuery('#campaignevent_triggerRestrictedDaysOfWeek_2').on('change', Mautic.campaignEventSelectDOW); mQuery('#campaignevent_triggerRestrictedDaysOfWeek_3').on('change', Mautic.campaignEventSelectDOW); mQuery('#campaignevent_triggerRestrictedDaysOfWeek_4').on('change', Mautic.campaignEventSelectDOW); mQuery('#campaignevent_triggerRestrictedDaysOfWeek_7').on('change', Mautic.campaignEventSelectDOW); } if (!response.hasOwnProperty('eventId')) { // There's nothing for us to do, so bail return; } // New action created so append it to the form var domEventId = 'CampaignEvent_' + response.eventId; var eventId = '#' + domEventId; Mautic.campaignBuilderLabels[domEventId] = (response.label) ? response.label : ''; if (!response.success && Mautic.campaignBuilderConnectionRequiresUpdate) { // Modal exited - check to see if a connection needs to be removed Mautic.campaignBuilderInstance.deleteConnection(Mautic.campaignBuilderLastConnection); } Mautic.campaignBuilderConnectionRequiresUpdate = false; Mautic.campaignBuilderUpdateLabel(domEventId); Mautic.campaignBuilderCanvasEvents[response.event.id] = response.event; if (response.deleted) { Mautic.campaignBuilderInstance.remove(document.getElementById(domEventId)); delete Mautic.campaignBuilderEventPositions[domEventId]; delete Mautic.campaignBuilderCanvasEvents[response.event.id]; } else if (response.updateHtml) { mQuery(eventId + " .campaign-event-content").replaceWith(response.updateHtml); } else if (response.eventHtml) { var newHtml = response.eventHtml; //append content var x = parseInt(mQuery('#droppedX').val()); var y = parseInt(mQuery('#droppedY').val()); Mautic.campaignBuilderEventPositions[domEventId] = { 'left': x, 'top': y }; mQuery(newHtml).appendTo('#CampaignCanvas'); mQuery(eventId).css({'left': x + 'px', 'top': y + 'px'}); Mautic.campaignBuilderRegisterAnchors(Mautic.getAnchorsForEvent(response.event), eventId); Mautic.campaignBuilderInstance.draggable(domEventId, Mautic.campaignDragOptions); //activate new stuff mQuery(eventId + " a[data-toggle='ajax']").click(function (event) { event.preventDefault(); return Mautic.ajaxifyLink(this, event); }); //initialize ajax'd modals mQuery(eventId + " a[data-toggle='ajaxmodal']").on('click.ajaxmodal', function (event) { event.preventDefault(); Mautic.ajaxifyModal(this, event); }); mQuery(eventId).off('.eventbuttons') .on('mouseover.eventbuttons', function() { mQuery(this).find('.campaign-event-buttons').removeClass('hide'); }) .on('mouseout.eventbuttons', function() { mQuery(this).find('.campaign-event-buttons').addClass('hide'); }) .on('dblclick.eventbuttons', function(event) { event.preventDefault(); mQuery(this).find('.btn-edit').first().click(); }); //initialize tooltips mQuery(eventId + " *[data-toggle='tooltip']").tooltip({html: true}); // Connect into last anchor clicked Mautic.campaignBuilderInstance.connect({ uuids: [ Mautic.campaignBuilderAnchorClicked, domEventId+'_top' ] }); } if (response.hasOwnProperty('clearCloneStorage')) { Mautic.hideCampaignEventPanel(); Mautic.clearCampaignEventClone(); } Mautic.campaignBuilderInstance.repaintEverything(); }; /** * Update the trigger hour based on the interval unit selected */ Mautic.campaignEventUpdateIntervalHours = function () { var hour = mQuery('#campaignevent_triggerHour').val(); var start = mQuery('#campaignevent_triggerRestrictedStartHour').val(); var stop = mQuery('#campaignevent_triggerRestrictedStopHour').val(); if (hour) { mQuery('#campaignevent_triggerRestrictedStartHour').val(''); mQuery('#campaignevent_triggerRestrictedStopHour').val(''); mQuery('#campaignevent_triggerRestrictedStartHour').prop('disabled', true); mQuery('#campaignevent_triggerRestrictedStopHour').prop('disabled', true); } else if (start || stop) { mQuery('#campaignevent_triggerHour').val(''); mQuery('#campaignevent_triggerHour').prop('disabled', true); } else { mQuery('#campaignevent_triggerHour').val(''); mQuery('#campaignevent_triggerRestrictedStartHour').val(''); mQuery('#campaignevent_triggerRestrictedStopHour').val(''); mQuery('#campaignevent_triggerHour').prop('disabled', false); mQuery('#campaignevent_triggerRestrictedStartHour').prop('disabled', false); mQuery('#campaignevent_triggerRestrictedStopHour').prop('disabled', false); } }; /** * Update DOW for weekday selection */ Mautic.campaignEventSelectDOW = function() { if (mQuery('#campaignevent_triggerRestrictedDaysOfWeek_7').prop('checked')) { mQuery('#campaignevent_triggerRestrictedDaysOfWeek_0').prop('checked', true); mQuery('#campaignevent_triggerRestrictedDaysOfWeek_1').prop('checked', true); mQuery('#campaignevent_triggerRestrictedDaysOfWeek_2').prop('checked', true); mQuery('#campaignevent_triggerRestrictedDaysOfWeek_3').prop('checked', true); mQuery('#campaignevent_triggerRestrictedDaysOfWeek_4').prop('checked', true); } mQuery('#campaignevent_triggerRestrictedDaysOfWeek_7').prop('checked', false); }; /** * Determine anchors to set up for the given event. * * This inspects the `connectionRestrictions` property * within the event's settings that were passed when * registering the event in your bundle's CampaignEventListener. * * @param event */ Mautic.getAnchorsForEvent = function (event) { var restrictions = Mautic.campaignBuilderConnectionRestrictions[event.type].target; // If all connections are restricted, only anchor the top if ( restrictions.decision.length === 1 && restrictions.decision[0] === "none" && restrictions.action.length === 1 && restrictions.action[0] === "none" && restrictions.condition.length === 1 && restrictions.condition[0] === "none" ) { return ['top']; } if (event.eventType === 'decision' || event.eventType === 'condition') { return ['top', 'yes', 'no']; } return ['top', 'bottom']; }; /** * Setup the campaign source view * * @param container * @param response */ Mautic.campaignSourceOnLoad = function (container, response) { //new action created so append it to the form var domEventId = 'CampaignEvent_' + response.sourceType; var eventId = '#' + domEventId; if (response.deleted) { Mautic.campaignBuilderInstance.remove(document.getElementById(domEventId)); delete Mautic.campaignBuilderEventPositions[domEventId]; mQuery('#campaignLeadSource_' + response.sourceType).prop('disabled', false); mQuery('#SourceList').trigger('chosen:updated'); // Check to see if all sources have been deleted if (!mQuery('.list-campaign-source:not(#CampaignEvent_newsource_hide)').length) { mQuery('#CampaignEvent_newsource_hide').attr('id', 'CampaignEvent_newsource'); Mautic.campaignBuilderPrepareNewSource(); } } else if (response.updateHtml) { mQuery(eventId + " .campaign-event-content").html(response.updateHtml); } else if (response.sourceHtml) { mQuery('#campaignLeadSource_' + response.sourceType).prop('disabled', true); mQuery('#SourceList').trigger('chosen:updated'); var newHtml = response.sourceHtml; if (mQuery('#CampaignEvent_newsource').length) { var x = mQuery('#CampaignEvent_newsource').position().left; var y = mQuery('#CampaignEvent_newsource').position().top; mQuery('#CampaignEvent_newsource').attr('id', 'CampaignEvent_newsource_hide'); Mautic.hideCampaignEventPanel(); var autoConnect = false; } else { //append content var x = parseInt(mQuery('#droppedX').val()); var y = parseInt(mQuery('#droppedY').val()); var autoConnect = true; } mQuery(newHtml).appendTo('#CampaignCanvas'); Mautic.campaignBuilderEventPositions[domEventId] = { 'left': x, 'top': y }; mQuery(eventId).css({'left': x + 'px', 'top': y + 'px'}); Mautic.campaignBuilderRegisterAnchors(['leadSource', 'leadSourceLeft', 'leadSourceRight'], eventId); Mautic.campaignBuilderInstance.draggable(domEventId, Mautic.campaignDragOptions); //activate new stuff mQuery(eventId + " a[data-toggle='ajax']").click(function (event) { event.preventDefault(); return Mautic.ajaxifyLink(this, event); }); //initialize ajax'd modals mQuery(eventId + " a[data-toggle='ajaxmodal']").on('click.ajaxmodal', function (event) { event.preventDefault(); Mautic.ajaxifyModal(this, event); }); mQuery(eventId).off('.eventbuttons') .on('mouseover.eventbuttons', function() { mQuery(this).find('.campaign-event-buttons').removeClass('hide'); }) .on('mouseout.eventbuttons', function() { mQuery(this).find('.campaign-event-buttons').addClass('hide'); }) .on('dblclick.eventbuttons', function(event) { event.preventDefault(); mQuery(this).find('.btn-edit').first().click(); }); //initialize tooltipslist-campaign-event mQuery(eventId + " *[data-toggle='tooltip']").tooltip({html: true}); if (autoConnect) { // Connect into last anchor clicked if (Mautic.campaignBuilderAnchorClicked.search('left') !== -1) { var source = domEventId + '_leadsourceright'; var target = Mautic.campaignBuilderAnchorClicked; } else { var source = Mautic.campaignBuilderAnchorClicked; var target = domEventId + '_leadsourceleft'; } Mautic.campaignBuilderInstance.connect({ uuids: [ source, target ] }); } // If there are no other events, auto click add action if (!mQuery('.list-campaign-event').length) { mQuery('.jtk-endpoint_anchor_leadsource.'+domEventId).trigger('click'); } } Mautic.campaignBuilderInstance.repaintEverything(); }; /** * Update a connectors label * * @param domEventId */ Mautic.campaignBuilderUpdateLabel = function (domEventId) { var theLabel = typeof Mautic.campaignBuilderLabels[domEventId] == 'undefined' ? '' : Mautic.campaignBuilderLabels[domEventId]; var currentConnections = Mautic.campaignBuilderInstance.select({ target: domEventId }); if (currentConnections.length > 0) { currentConnections.each(function(conn) { //remove current label var overlays = conn.getOverlays(); if (overlays.length > 0) { for (var i = 0; i <= overlays.length; i++ ) { if ( typeof overlays[i] != 'undefined' && overlays[i].type == 'Label') { conn.removeOverlay(overlays[i].id); } } } if (theLabel) { conn.addOverlay(["Label", { label: theLabel, location: 0.65, cssClass: "jtk-label", id: conn.sourceId + "_" + conn.targetId + "_connectionLabel" }]); } }); } }; /** * Launch campaign builder modal */ Mautic.launchCampaignEditor = function() { Mautic.stopIconSpinPostEvent(); mQuery('body').css('overflow-y', 'hidden'); mQuery('#campaign-builder').trigger('campaign-builder:show'); // Center new source if (mQuery('#CampaignEvent_newsource').length) { Mautic.campaignBuilderPrepareNewSource(); } if (Mautic.campaignBuilderCanvasSettings) { Mautic.campaignBuilderInstance.setSuspendDrawing(true); Mautic.campaignBuilderReconnectEndpoints(); Mautic.campaignBuilderInstance.setSuspendDrawing(false, true); } Mautic.campaignBuilderInstance.repaintEverything(); }; /** * Launch campaign preview view */ Mautic.launchCampaignPreview = function() { Mautic.stopIconSpinPostEvent(); if (Mautic.campaignBuilderCanvasSettings) { Mautic.campaignBuilderInstance.setSuspendDrawing(true); Mautic.campaignBuilderReconnectEndpoints(); Mautic.campaignBuilderInstance.setSuspendDrawing(false, true); } Mautic.campaignBuilderInstance.repaintEverything(); }; /** * * @type {{source: {leadsource: {source: Array, action: [*], condition: [*], decision: [*]}, leadsourceleft: {source: [*], action: Array, condition: Array, decision: Array}, leadsourceright: {source: [*], action: Array, condition: Array, decision: Array}}, action: {top: {source: [*], action: Array, condition: [*], decision: [*]}, bottom: {source: Array, action: Array, condition: [*], decision: [*]}}, condition: {top: {source: [*], action: [*], condition: [*], decision: [*]}, yes: {source: Array, action: [*], condition: [*], decision: [*]}, no: {source: Array, action: [*], condition: [*], decision: [*]}}, decision: {top: {action: [*], source: [*], condition: [*], decision: Array}, yes: {source: Array, action: [*], condition: [*], decision: Array}, no: {source: Array, action: [*], condition: [*], decision: Array}}}} */ Mautic.campaignBuilderConnectionsMap = { // source 'source': { // source anchors 'leadsource': { // target 'source': [], 'action': ['top'], // target anchors 'condition': ['top'], 'decision': ['top'], }, 'leadsourceleft': { 'source': ['leadsourceright'], 'action': [], 'condition': [], 'decision': [] }, 'leadsourceright': { 'source': ['leadsourceleft'], 'action': [], 'condition': [], 'decision': [] } }, 'action': { 'top': { 'source': ['leadsource'], 'action': ['bottom'], 'condition': ['yes', 'no'], 'decision': ['yes', 'no'] }, 'bottom': { 'source': [], 'action': ['top'], 'condition': ['top'], 'decision': ['top'] } }, 'condition': { 'top': { 'source': ['leadsource'], 'action': ['bottom'], 'condition': ['yes', 'no'], 'decision': ['yes', 'no'] }, 'yes': { 'source': [], 'action': ['top'], 'condition': ['top'], 'decision': ['top'] }, 'no': { 'source': [], 'action': ['top'], 'condition': ['top'], 'decision': ['top'] } }, 'decision': { 'top': { 'action': ['bottom'], 'source': ['leadsource'], 'condition': ['yes', 'no'], 'decision': [], }, 'yes': { 'source': [], 'action': ['top'], 'condition': ['top'], 'decision': [], }, 'no': { 'source': [], 'action': ['top'], 'condition': ['top'], 'decision': [], } } }; Mautic.campaignBuilderAnchorDefaultColor = '#d5d4d4'; Mautic.campaignEndpointDefinitions = { 'top': { anchors: [0.5, 0, 0, -1, 0, 0], isTarget: true }, 'bottom': { anchors: [0.5, 1, 0, 1, 0, 0], isTarget: false }, 'yes': { anchors: [0, 1, 0, 1, 30, 0], connectorColor: '#00b49c', isTarget: false }, 'no': { anchors: [1, 1, 0, 1, -30, 0], connectorColor: '#f86b4f', isTarget: false }, 'leadSource': { anchors: [0.5, 1, 0, 1, 0, 0], isTarget: false }, 'leadSourceLeft': { anchors: [0, 0.5, -1, 0, -1, 0], connectorColor: '#fdb933', isTarget: true, connectorStyle: 'Straight' }, 'leadSourceRight': { anchors: [1, 0.5, 1, 0, 1, 0], connectorColor: '#fdb933', isTarget: false, connectorStyle: 'Straight' } }; /** * Push callbacks to these events * * @type {{connection: Array, connectionDetached: Array, connectionMoved: Array, beforeDrop: Array}} */ Mautic.campaignConnectionCallbacks = { // sourceEndpoint, targetEndpoint, connection 'beforeDetach': [], // sourceEndpoint, targetEndpoint, endpoint, source, sourceId 'beforeDrag': [], // sourceEndpoint, targetEndpoint, endpoint, source, sourceId 'beforeStartDetach': [], // sourceEndpoint, targetEndpoint, endpoint, source, sourceId, connection 'beforeDrop': [], //sourceEndpoint, endpoint, event 'onHover': [], // no arguments 'beforeAnchorsRegistered': [], 'afterAnchorsRegistered': [], 'beforeEndpointsRegistered': [], 'beforeEndpointsReconnected': [], 'afterEndpointsReconnected': [] }; Mautic.campaignBuilderAnchorClicked = false; Mautic.campaignBuilderEventPositions = {}; Mautic.prepareCampaignCanvas = function() { if (typeof Mautic.campaignBuilderInstance == 'undefined') { Mautic.campaignBuilderInstance = jsPlumb.getInstance({ Container: document.querySelector("#CampaignCanvas") }); Mautic.campaignEndpoints = {}; var startingPosition; Mautic.campaignDragOptions = { start: function (params) { //double clicking activates the stop function so add a catch to prevent unnecessary ajax calls startingPosition = { top: params.el.offsetTop, left: params.el.offsetLeft, }; }, stop: function (params) { var endingPosition = { top: params.finalPos[0], left: params.finalPos[1] }; if (startingPosition.left !== endingPosition.left || startingPosition.top !== endingPosition.top) { //update coordinates Mautic.campaignBuilderEventPositions[mQuery(params.el).attr('id')] = { 'left': parseInt(endingPosition.left), 'top': parseInt(endingPosition.top) }; var campaignId = mQuery('#campaignId').val(); var query = "action=campaign:updateCoordinates&campaignId=" + campaignId + "&droppedX=" + endingPosition.top + "&droppedY=" + endingPosition.left + "&eventId=" + mQuery(params.el).attr('id'); mQuery.ajax({ url: mauticAjaxUrl, type: "POST", data: query, dataType: "json", error: function (request, textStatus, errorThrown) { Mautic.processAjaxError(request, textStatus, errorThrown); } }); } }, containment:true }; Mautic.campaignBuilderEventDimensions = { 'width': 200, 'height': 45, 'anchor': 10, 'wiggleWidth': 30, 'wiggleHeight': 50 }; // Store labels Mautic.campaignBuilderLabels = {}; // Update the labels on connection/disconnection Mautic.campaignBuilderInstance.bind("connection", function (info, originalEvent) { // Mark the connection so it can be removed if the form is cancelled Mautic.campaignBuilderConnectionRequiresUpdate = false; Mautic.campaignBuilderLastConnection = info.connection; // If there is a switch between active/inactive anchors, reload the form var epDetails = Mautic.campaignBuilderGetEndpointDetails(info.sourceEndpoint); var targetElementId = info.targetEndpoint.elementId; var previousConnection = mQuery('#'+targetElementId).attr('data-connected'); var editButton = mQuery('#'+targetElementId).find('a.btn-edit'); var editUrl = editButton.attr('href'); if (editUrl) { var anchorQueryParams = 'anchor=' + epDetails.anchorName + "&anchorEventType=" + epDetails.eventType; if (editUrl.search('anchor=') !== -1) { editUrl.replace(/anchor=(.*?)$/, anchorQueryParams); } else { var delimiter = (editUrl.indexOf('?') === -1) ? '?' : '&'; editUrl = editUrl + delimiter + anchorQueryParams; } editButton.attr('data-href', editUrl); if (previousConnection && previousConnection != epDetails.anchorName && (previousConnection == 'no' || epDetails.anchorName == 'no')) { editButton.attr('data-prevent-dismiss', true); Mautic.campaignBuilderConnectionRequiresUpdate = true; editButton.trigger('click'); } } mQuery('#'+targetElementId).attr('data-connected', epDetails.anchorName); Mautic.campaignBuilderUpdateLabel(info.connection.targetId); info.targetEndpoint.setPaintStyle( { fill: info.connection.getPaintStyle().stroke } ); info.sourceEndpoint.setPaintStyle( { fill: info.connection.getPaintStyle().stroke } ); }); Mautic.campaignBuilderInstance.bind("connectionDetached", function (info, originalEvent) { Mautic.campaignBuilderUpdateLabel(info.connection.targetId); info.targetEndpoint.setPaintStyle( { fill: "#d5d4d4" } ); var currentConnections = info.sourceEndpoint.connections.length; // JavaScript counts index which still accounts for old connection currentConnections -= 1; if (!currentConnections) { info.sourceEndpoint.setPaintStyle( { fill: "#d5d4d4" } ); } }); Mautic.campaignBuilderInstance.bind("connectionMoved", function (info, originalEvent) { Mautic.campaignBuilderUpdateLabel(info.connection.originalTargetId); info.originalTargetEndpoint.setPaintStyle( { fill: "#d5d4d4" } ); Mautic.campaignBuilderUpdateLabel(info.connection.newTargetId); info.newTargetEndpoint.setPaintStyle( { fill: info.newSourceEndpoint.getPaintStyle().fill } ); }); mQuery('.builder-content').scroll(function () { Mautic.campaignBuilderInstance.repaintEverything(); }); mQuery.each(Mautic.campaignConnectionCallbacks.beforeEndpointsRegistered, function (index, callback) { callback(); }); mQuery.each(Mautic.campaignEndpointDefinitions, function (ep, definition) { Mautic.campaignBuilderRegisterEndpoint(ep, definition); }); //manually loop through each so a UUID can be set for reconnecting connections mQuery.each(Mautic.campaignConnectionCallbacks.beforeAnchorsRegistered, function (index, callback) { callback(); }); mQuery("#CampaignCanvas div[data-event-id]").each(function () { var event = Mautic.campaignBuilderCanvasEvents[mQuery(this).data('eventId')]; Mautic.campaignBuilderRegisterAnchors(Mautic.getAnchorsForEvent(event), this); }); mQuery("#CampaignCanvas div.list-campaign-event.list-campaign-source").not('#CampaignEvent_newsource').not('#CampaignEvent_newsource_hide').each(function () { Mautic.campaignBuilderRegisterAnchors(['bottom'], this); }); mQuery("#CampaignCanvas div.list-campaign-leadsource").not('#CampaignEvent_newsource').not('#CampaignEvent_newsource_hide').each(function () { Mautic.campaignBuilderRegisterAnchors(['leadSource', 'leadSourceLeft', 'leadSourceRight'], this); }); mQuery.each(Mautic.campaignConnectionCallbacks.afterAnchorsRegistered, function (index, callback) { callback(); }); if (mQuery('.preview').length) { Mautic.launchCampaignPreview(); } else { //enable drag and drop Mautic.campaignBuilderInstance.draggable( document.querySelectorAll("#CampaignCanvas .draggable"), Mautic.campaignDragOptions ); } } }; /** * Validate a connection before it can be made * * @param params * @returns {boolean} */ Mautic.campaignBeforeDropCallback = function(params) { var sourceEndpoint = Mautic.campaignBuilderGetEndpointDetails(params.connection.endpoints[0]); var targetEndpoint = Mautic.campaignBuilderGetEndpointDetails(params.dropEndpoint); var callbackAllowed = null; mQuery.each(Mautic.campaignConnectionCallbacks.beforeDrop, function(index, callback) { var result = callback(sourceEndpoint, targetEndpoint, params); if (null !== result) { callbackAllowed = result; return false; } }); if (null !== callbackAllowed) { return callbackAllowed; } if (!Mautic.campaignBuilderValidateConnection(sourceEndpoint, targetEndpoint.eventType, targetEndpoint.event)){ return false; } if (mQuery.inArray(targetEndpoint.anchorName, ['top', 'leadsourceleft', 'leadsourceright'])) { //ensure two events aren't looping var sourceConnections = Mautic.campaignBuilderInstance.select({ source: params.targetId }); var loopDetected = false; sourceConnections.each(function (conn) { if (conn.sourceId == targetEndpoint.elementId && conn.targetId == sourceEndpoint.elementId) { loopDetected = true; return false; } }); } //ensure that the connections are not looping back into the same event if (params.sourceId == params.targetId) { return false; } // ensure the map allows this connection var allowedConnections = Mautic.campaignBuilderConnectionsMap[sourceEndpoint.eventType][sourceEndpoint.anchorName][targetEndpoint.eventType]; var allowed = mQuery.inArray(targetEndpoint.anchorName, allowedConnections) !== -1; if (allowed) { //ensure that a top only has one connection at a time unless connected from a source if (params.dropEndpoint.connections.length > 0) { // Replace the connection mQuery.each(params.dropEndpoint.connections, function(key, conn) { Mautic.campaignBuilderInstance.deleteConnection(conn); }); } } return allowed; }; /** * Process beforeDetach event callbacks * * @param connection * @returns {*} */ Mautic.campaignBeforeDetachCallback = function(connection) { var sourceEndpoint = Mautic.campaignBuilderGetEndpointDetails(connection.sourceId); var targetEndpoint = Mautic.campaignBuilderGetEndpointDetails(connection.targetId); var callbackAllowed = null; mQuery.each(Mautic.campaignConnectionCallbacks.beforeDetach, function (index, callback) { var result = callback(sourceEndpoint, targetEndpoint, connection); if (null !== result) { callbackAllowed = result; return false; } }); if (null !== callbackAllowed) { return callbackAllowed; } return true; }; /** * Process beforeDetach event callbacks * * @param connection */ Mautic.campaignBeforeDragCallback = function(endpoint, source, sourceId) { var sourceEndpoint = Mautic.campaignBuilderGetEndpointDetails(sourceId); var targetEndpoint = Mautic.campaignBuilderGetEndpointDetails(endpoint); var callbackAllowed = null; mQuery.each(Mautic.campaignConnectionCallbacks.beforeDrag, function (index, callback) { var result = callback(sourceEndpoint, targetEndpoint, endpoint, source, sourceId); if (null !== result) { callbackAllowed = result; return false; } }); if (null !== callbackAllowed) { return callbackAllowed; } return true; }; /** * Process beforeDetach event callbacks * * @param endpoint * @param source * @param sourceId * @param connection * @returns {*} */ Mautic.campaignBeforeStartDetachCallback = function(endpoint, source, sourceId, connection) { var sourceEndpoint = Mautic.campaignBuilderGetEndpointDetails(sourceId); var targetEndpoint = Mautic.campaignBuilderGetEndpointDetails(endpoint); var callbackAllowed = null; mQuery.each(Mautic.campaignConnectionCallbacks.beforeStartDetach, function (index, callback) { var result = callback(sourceEndpoint, targetEndpoint, endpoint, source, sourceId, connection); if (null !== result) { callbackAllowed = result; return false; } }); if (null !== callbackAllowed) { return callbackAllowed; } return true; }; /** * Process beforeDetach event callbacks * * @param connection */ Mautic.campaignHoverCallback = function(sourceEndpoint, endpoint, event) { var callbackAllowed = null; mQuery.each(Mautic.campaignConnectionCallbacks.onHover, function (index, callback) { var result = callback(sourceEndpoint, endpoint, event); if (null !== result) { callbackAllowed = result; return false; } }); if (null !== callbackAllowed) { return callbackAllowed; } return true; }; /** * Enable/Disable timeframe settings if the toggle for immediate trigger is changed */ Mautic.campaignToggleTimeframes = function() { if (mQuery('#campaignevent_triggerMode_2').length) { var immediateChecked = mQuery('#campaignevent_triggerMode_0').prop('checked'); var intervalChecked = mQuery('#campaignevent_triggerMode_1').prop('checked'); var dateChecked = mQuery('#campaignevent_triggerMode_2').prop('checked'); } else { var immediateChecked = false; var intervalChecked = mQuery('#campaignevent_triggerMode_0').prop('checked'); var dateChecked = mQuery('#campaignevent_triggerMode_1').prop('checked'); } if (mQuery('#campaignevent_triggerInterval').length) { if (immediateChecked) { mQuery('#triggerInterval').addClass('hide'); mQuery('#triggerDate').addClass('hide'); } else if (intervalChecked) { mQuery('#triggerInterval').removeClass('hide'); mQuery('#triggerDate').addClass('hide'); } else if (dateChecked) { mQuery('#triggerInterval').addClass('hide'); mQuery('#triggerDate').removeClass('hide'); } } }; /** * Close campaign builder */ Mautic.closeCampaignBuilder = function() { // Disable buttons mQuery('.btns-builder').find('button').prop('disabled', true); var builderCss = { margin: "0", padding: "0", border: "none", width: "100%", height: "100%" }; var panelHeight = (mQuery('.builder-content').css('right') == '0px') ? mQuery('.builder-panel').height() : 0, panelWidth = (mQuery('.builder-content').css('right') == '0px') ? 0 : mQuery('.builder-panel').width(), spinnerLeft = (mQuery(window).width() - panelWidth - 60) / 2, spinnerTop = (mQuery(window).height() - panelHeight - 60) / 2; var overlay = mQuery('