-/**
- * Created by aditya on 6/12/14.
- */
-
-
-(function(angular, $, _) {
-
- var partialUrl = function(relPath) {
- //console.log(CRM.resourceUrls['civicrm']);
- //return CRM.resourceUrls['civicrm'] + '/partials/abtesting/' + relPath;
- return '/drupal-7.28/sites/all/modules/civicrm/partials/abtesting/' + relPath;
-
-
- };
-
- var crmMailingAB = angular.module('crmMailingAB', ['ngRoute', 'ui.utils']);
-
- crmMailingAB.run(function($rootScope, $templateCache) {
- $rootScope.$on('$viewContentLoaded', function() {
- $templateCache.removeAll();
- });
- });
-
- crmMailingAB.config(['$routeProvider',
- function($routeProvider) {
- $routeProvider.when('/mailing', {
- template: '<h1>sdfs</h1>',
- controller: 'mailingListCtrl',
- resolve: {
- mailingList: function($route, crmApi) {
- return crmApi('Mailing', 'get', {});
- }
- }
- });
-
- $routeProvider.when('/mailing/abtesting', {
- templateUrl: partialUrl('main.html'),
- controller: 'TabsDemoCtrl',
- resolve: {
- metaData: function($route, crmApi) {
- return crmApi('Group', 'get', {});
- },
- mailingList: function($route, crmApi) {
- return crmApi('Mailing', 'get', {});
- }
- }
- });
+(function (angular, $, _) {
+
+ var partialUrl = function (relPath, module) {
+ if (!module) {
+ module = 'crmMailingAB';
+ }
+ return CRM.resourceUrls.civicrm + '/partials/' + module + '/' + relPath;
+ };
+
+ angular.module('crmMailingAB', ['ngRoute', 'ui.utils', 'ngSanitize', 'crmUi', 'crmAttachment', 'crmMailing', 'crmD3']);
+ angular.module('crmMailingAB').config([
+ '$routeProvider',
+ function ($routeProvider) {
+ $routeProvider.when('/abtest', {
+ templateUrl: partialUrl('list.html'),
+ controller: 'CrmMailingABListCtrl',
+ resolve: {
+ mailingABList: function ($route, crmApi) {
+ return crmApi('MailingAB', 'get', {rowCount: 0});
+ }
}
- ]);
-//-----------------------------------------
- // Add a new record by name.
- // Ex: <crmAddName crm-options="['Alpha','Beta','Gamma']" crm-var="newItem" crm-on-add="callMyCreateFunction(newItem)" />
-
- crmMailingAB.controller('TabsDemoCtrl', function($scope, crmApi, metaData, mailingList) {
-
- $scope.groups = metaData.values;
- $scope.mailings = mailingList.values;
- $scope.tab_val=0;
- $scope.max_tab=0;
- $scope.campaign_clicked= function(){
- if($scope.max_tab >= 0 ){
- $scope.tab_val =0;
- }
- };
- $scope.compose_clicked=function(){
- if($scope.max_tab >=1){
- $scope.tab_val =1;
- }
- };
- $scope.rec_clicked=function(){
- if($scope.max_tab >=2){
- $scope.tab_val =2;
- }
- };
- $scope.preview_clicked=function(){
- if($scope.max_tab>=3){
- $scope.tab_val=3;
- }
- };
- $scope.templates =
- [ { name: 'Subject Lines', url: partialUrl('subject_lines.html')},
- { name: 'From Name', url: partialUrl('from_name.html')},
- {name:'Two different Emails',url: partialUrl('two_emails.html')} ];
- $scope.template = $scope.templates[0];
-
- $scope.slide_value = 0;
-
- $scope.setifyes= function(val){
- if(val ==1) {
- $scope.ifyes = true;
- }
- else
- $scope.ifyes=false;
- };
-
- $scope.send_date ="01/01/2000";
-
- $scope.mailA={};
-
- $scope.mailB={};
- $scope.save=function(dat){
-
- var result= crmApi('Mailing', 'create',dat, true);
- console.log("Ac "+result);
- };
-
- $scope.init=function(par){
-
- $scope.whatnext=par.toString()
+ });
+ $routeProvider.when('/abtest/:id', {
+ templateUrl: partialUrl('edit.html'),
+ controller: 'CrmMailingABEditCtrl',
+ resolve: {
+ abtest: function ($route, CrmMailingAB) {
+ var abtest = new CrmMailingAB($route.current.params.id == 'new' ? null : $route.current.params.id);
+ return abtest.load();
+ }
}
+ });
+ $routeProvider.when('/abtest/:id/report', {
+ templateUrl: partialUrl('report.html'),
+ controller: 'CrmMailingABReportCtrl',
+ resolve: {
+ abtest: function ($route, CrmMailingAB) {
+ var abtest = new CrmMailingAB($route.current.params.id);
+ return abtest.load();
+ }
+ }
+ });
+ }
+ ]);
+
+ angular.module('crmMailingAB').controller('CrmMailingABListCtrl', function ($scope, mailingABList, crmMailingABCriteria, crmMailingABStatus) {
+ var ts = $scope.ts = CRM.ts('CiviMail');
+ $scope.mailingABList = mailingABList.values;
+ $scope.crmMailingABCriteria = crmMailingABCriteria;
+ $scope.crmMailingABStatus = crmMailingABStatus;
+ });
+
+ angular.module('crmMailingAB').controller('CrmMailingABEditCtrl', function ($scope, abtest, crmMailingABCriteria, crmMailingMgr, crmMailingPreviewMgr, crmStatus, $q, $location) {
+ $scope.abtest = abtest;
+ var ts = $scope.ts = CRM.ts('CiviMail');
+ $scope.crmMailingABCriteria = crmMailingABCriteria;
+ $scope.crmMailingConst = CRM.crmMailing;
+ $scope.partialUrl = partialUrl;
+
+ $scope.isSubmitted = function isSubmitted() {
+ return _.size(abtest.mailings.a.jobs) > 0 || _.size(abtest.mailings.b.jobs) > 0;
+ };
+ $scope.sync = function sync() {
+ abtest.mailings.a.name = ts('Test A (%1)', {1: abtest.ab.name});
+ abtest.mailings.b.name = ts('Test B (%1)', {1: abtest.ab.name});
+ abtest.mailings.c.name = ts('Winner (%1)', {1: abtest.ab.name});
+
+ var criteria = crmMailingABCriteria.get(abtest.ab.testing_criteria_id);
+ if (criteria) {
+ // TODO review fields exposed in UI and make sure the sync rules match
+ switch (criteria.name) {
+ case 'Subject lines':
+ crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [
+ 'name',
+ 'groups',
+ 'mailings',
+ 'subject'
+ ]);
+ break;
+ case 'From names':
+ crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [
+ 'name',
+ 'groups',
+ 'mailings',
+ 'from_name',
+ 'from_email'
+ ]);
+ break;
+ case 'Two different emails':
+ crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [
+ 'name',
+ 'groups',
+ 'mailings',
+ 'subject',
+ 'from_name',
+ 'from_email',
+ 'body_html',
+ 'body_text'
+ ]);
+ break;
+ default:
+ throw "Unrecognized testing_criteria";
+ }
+ }
+ crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings.a, ['name']);
+ return $q.when(true);
+ };
- });
-
- crmMailingAB.directive('nexttab', function() {
- return {
- // Restrict it to be an attribute in this case
- restrict: 'A',
-
- priority: 500,
- // responsible for registering DOM listeners as well as updating the DOM
- link: function(scope, element, attrs) {
-
- $(element).parent().parent().parent().parent().tabs(scope.$eval(attrs.nexttab));
- var myarr = new Array(1,2,3)
- $(element).parent().parent().parent().parent().tabs({disabled:myarr});
-
- $(element).on("click",function() {
- scope.tab_val=scope.tab_val +1;
-
- scope.max_tab= Math.max(scope.tab_val,scope.max_tab);
- var myArray1 = new Array( );
- for ( var i = scope.max_tab+1; i < 4; i++ ) {
- myArray1.push(i);
- }
- $(element).parent().parent().parent().parent().parent().tabs( "option", "disabled", myArray1 );
- $(element).parent().parent().parent().parent().parent().tabs("option", "active", scope.tab_val);
- scope.$apply();
- console.log("Adir");
- });
- }
- };
- });
-
- crmMailingAB.directive('prevtab', function() {
- return {
- // Restrict it to be an attribute in this case
- restrict: 'A',
- priority: 500,
- // responsible for registering DOM listeners as well as updating the DOM
- link: function(scope, element, attrs) {
-
-
-
- $(element).on("click",function() {
- var temp= scope.tab_val -1 ;
- scope.tab_val=scope.tab_val -1;
-
- console.log(temp);
- if(temp==3){
-
- }
- else {
- $(element).parent().parent().parent().parent().parent().tabs("option", "active", temp);
- }
-
- scope.$apply();
-
- });
- }
- };
- });
-
- crmMailingAB.directive('groupselect',function(){
- return {
- restrict : 'AE',
- link: function(scope,element, attrs){
- $(element).select2({width:"400px",placeholder: "Select the groups you wish to include"});
- $(element).select2("data",groups)
- }
- };
-
- });
-
- crmMailingAB.directive('sliderbar',function(){
- return{
- restrict: 'AE',
- link: function(scope,element, attrs){
- $(element).slider({min:1});
- $(element).slider({
- slide: function( event, ui ) {
- scope.slide_value = ui.value;
- scope.$apply();
- }
- });
- }
- };
- });
-
- crmMailingAB.directive('tpmax',function(){
- return {
- restrict: 'E',
- link: function(scope,element,attr){
- scope.$watch('automated', function(val) {
- if(val=="Yes") {
- $(element).dialog({
- title: 'Automated A/B Testing',
- width: 800,
- height: 600,
- closed: false,
- cache: false,
- modal: true
- });
- }
- });
-
- $(element).find("#closebutton").on("click",function(){
- $(element).dialog("close");
- });
- }
- };
- });
-
- crmMailingAB.directive('numbar',function(){
- return{
- restrict: 'AE',
- link: function(scope,element, attrs){
- $(element).spinner({max:attrs.numbar,min:0});
- }
- };
- });
-
- crmMailingAB.directive('datepick',function(){
- return {
- scope :{
- foo : '=send_date'
- },
- restrict: 'AE',
- link: function(scope,element,attrs){
- $(element).datepicker({
- onSelect: function(date) {
- $(".ui-datepicker a").removeAttr("href");
- scope.foo =date;
- console.log(date);
- }
- });
- }
- };
- });
-
- crmMailingAB.directive('submitform',function(){
- return {
- restrict:'A',
- priority: 1000,
- link: function(scope,element,attrs){
- $(element).on("click",function() {
-
- console.log("clicked");
- scope.save({
- "sequential": 1,
- "name": "Aditya Nambiar",
- "subject": scope.mailA.subj,
- "created_id": "2",
- "from_email": scope.mailA.fromEmail,
- "body_text": scope.mailA.body
-
- });
- console.log("Truth "+ scope.whatnext)
-
- if(scope.whatnext=="3"){
- console.log("sdf");
- scope.mailB.subj=scope.mailA.subj;
- scope.mailB.body=scope.mailA.body;
-
- }
- else if(scope.whatnext=="2"){
- scope.mailB.fromEmail=scope.mailA.fromEmail;
- scope.mailB.body=scope.mailA.body;
+ // @return Promise
+ $scope.save = function save() {
+ $scope.sync();
+ return crmStatus({start: ts('Saving...'), success: ts('Saved')}, abtest.save().then(updateUrl));
+ };
- }
-
+ // @return Promise
+ $scope.previewMailing = function previewMailing(mailingName, mode) {
+ $scope.sync();
+ return crmMailingPreviewMgr.preview(abtest.mailings[mailingName], mode);
+ };
- scope.save({
- "sequential": 1,
- "name": "Aditya Nambiar",
- "subject": scope.mailB.subj,
- "created_id": "2",
- "from_email": scope.mailB.fromEmail,
- "body_text": scope.mailB.body
+ // @return Promise
+ $scope.sendTest = function sendTest(mailingName, recipient) {
+ $scope.sync();
+ return crmStatus({start: ts('Saving...'), success: ''}, abtest.save().then(updateUrl))
+ .then(function () {
+ crmMailingPreviewMgr.sendTest(abtest.mailings[mailingName], recipient);
+ });
+ };
- });
+ // @return Promise
+ $scope.delete = function () {
+ return crmStatus({start: ts('Deleting...'), success: ts('Deleted')}, abtest.delete().then(leave));
+ };
- });
- }
- };
+ // @return Promise
+ $scope.submit = function submit() {
+ $scope.sync();
+ return crmStatus({start: ts('Saving...'), success: ''}, abtest.save())
+ .then(function () {
+ return crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, abtest.submitTest());
+ // Note: We're going to leave, so we don't care that submit() modifies several server-side records.
+ // If we stayed on this page, then we'd care about updating and call: abtest.submitTest().then(...abtest.load()...)
+ })
+ .then(leave);
+ };
+ function leave() {
+ $location.path('abtest');
+ $location.replace();
+ }
+
+ function updateCriteriaName() {
+ var criteria = crmMailingABCriteria.get($scope.abtest.ab.testing_criteria_id);
+ $scope.criteriaName = criteria ? criteria.name : null;
+ }
+
+ // Transition URL "/abtest/new" => "/abtest/123"
+ function updateUrl() {
+ var parts = $location.path().split('/'); // e.g. "/abtest/new" or "/abtest/123/wizard"
+ if (parts[2] != $scope.abtest.ab.id) {
+ parts[2] = $scope.abtest.ab.id;
+ $location.path(parts.join('/'));
+ $location.replace();
+ // FIXME: Angular unnecessarily refreshes UI
+ // WARNING: Changing the URL triggers a full reload. Any pending AJAX operations
+ // could be inconsistently applied. Run updateUrl() after other changes complete.
+ }
+ }
+
+ // initialize
+ updateCriteriaName();
+ $scope.sync();
+ $scope.$watch('abtest.ab.testing_criteria_id', updateCriteriaName);
+ });
+
+ angular.module('crmMailingAB').controller('CrmMailingABReportCtrl', function ($scope, abtest, crmApi, crmMailingPreviewMgr, dialogService) {
+ var ts = $scope.ts = CRM.ts('CiviMail');
+
+ $scope.abtest = abtest;
+
+ $scope.stats = {};
+ crmApi('Mailing', 'stats', {mailing_id: abtest.ab.mailing_id_a}).then(function(data){
+ $scope.stats.a = data.values[abtest.ab.mailing_id_a];
});
-
- crmMailingAB.directive('nextbutton',function(){
- return {
- restrict: 'AE',
- replace:'true',
- template:'<div class="crm-submit-buttons" id="campaignbutton">'+
- '<div class = "crm-button crm-button-type-upload crm-button_qf_Contact_upload_view" >' +
- '<input type="submit" value="Next" id="campaignbutton _qf_Contact_upload_view-top" class="btn btn-primary" nexttab={{tab_val}}>'+
- '</div></div>'
-
- };
+ crmApi('Mailing', 'stats', {mailing_id: abtest.ab.mailing_id_b}).then(function(data){
+ $scope.stats.b = data.values[abtest.ab.mailing_id_b];
});
-
- crmMailingAB.directive('prevbutton',function(){
- return {
- restrict: 'AE',
- replace:'true',
- template:'<div class="crm-submit-buttons" >'+
- '<div class = "crm-button crm-button-type-upload crm-button_qf_Contact_upload_view" >' +
- '<input type="submit" value="Previous" id="campaignbutton _qf_Contact_upload_view-top" class="btn btn-primary" prevtab={{tab_val}}>'+
- '</div></div>'
-
- };
+ crmApi('Mailing', 'stats', {mailing_id: abtest.ab.mailing_id_c}).then(function(data){
+ $scope.stats.c = data.values[abtest.ab.mailing_id_c];
});
-
-
+ $scope.previewMailing = function previewMailing(mailingName, mode) {
+ return crmMailingPreviewMgr.preview(abtest.mailings[mailingName], mode);
+ };
+ $scope.selectWinner = function selectWinner(mailingName) {
+ var model = {
+ abtest: abtest,
+ mailingName: mailingName
+ };
+ var options = {
+ autoOpen: false,
+ modal: true,
+ title: ts('Select Winner (%1)', {
+ 1: mailingName.toUpperCase()
+ })
+ };
+ return dialogService.open('selectWinnerDialog', partialUrl('selectWinner.html'), model, options);
+ };
+ });
+
+
+ angular.module('crmMailingAB').controller('CrmMailingABWinnerDialogCtrl', function ($scope, $timeout, dialogService, crmMailingMgr, crmStatus) {
+ var ts = $scope.ts = CRM.ts('CiviMail');
+ var abtest = $scope.abtest = $scope.model.abtest;
+ var mailingName = $scope.model.mailingName;
+
+ var titles = {a: ts('Mailing A'), b: ts('Mailing B')};
+ $scope.mailingTitle = titles[mailingName];
+
+ function init() {
+ // When using dialogService with a button bar, the major button actions
+ // need to be registered with the dialog widget (and not embedded in
+ // the body of the dialog).
+ var buttons = {};
+ buttons[ts('Select Winner')] = function () {
+ crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings[mailingName], [
+ 'name',
+ 'groups',
+ 'mailings',
+ 'scheduled_date'
+ ]);
+ crmStatus({start: ts('Saving...'), success: ''}, abtest.save())
+ .then(function () {
+ return crmStatus({start: ts('Submitting...'), success: ts('Submitted')},
+ abtest.submitFinal().then(function(){
+ return abtest.load();
+ }));
+ })
+ .then(function(){
+ dialogService.close('selectWinnerDialog', abtest);
+ });
+ };
+ buttons[ts('Cancel')] = function () {
+ dialogService.cancel('selectWinnerDialog');
+ };
+ dialogService.setButtons('selectWinnerDialog', buttons);
+ }
+
+ $timeout(init);
+ });
})(angular, CRM.$, CRM._);
-