From 679996bbe737f7011fabf59c268b9fbd6b8ebefe Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Tue, 7 Apr 2015 17:16:54 -0700 Subject: [PATCH] CRM-16145 - crmMailingAB - Split controllers into separate files --- CRM/Mailing/Info.php | 4 +- ang/crmMailingAB.js | 44 +++++ ang/crmMailingAB/EditCtrl.js | 144 ++++++++++++++ ang/crmMailingAB/ListCtrl.js | 12 ++ ang/crmMailingAB/NewCtrl.js | 11 ++ ang/crmMailingAB/ReportCtrl.js | 52 +++++ ang/crmMailingAB/WinnerDialogCtrl.js | 52 +++++ js/angular-crmMailingAB.js | 282 --------------------------- 8 files changed, 318 insertions(+), 283 deletions(-) create mode 100644 ang/crmMailingAB.js create mode 100644 ang/crmMailingAB/EditCtrl.js create mode 100644 ang/crmMailingAB/ListCtrl.js create mode 100644 ang/crmMailingAB/NewCtrl.js create mode 100644 ang/crmMailingAB/ReportCtrl.js create mode 100644 ang/crmMailingAB/WinnerDialogCtrl.js delete mode 100644 js/angular-crmMailingAB.js diff --git a/CRM/Mailing/Info.php b/CRM/Mailing/Info.php index 816a30ca95..ff3529b711 100644 --- a/CRM/Mailing/Info.php +++ b/CRM/Mailing/Info.php @@ -78,7 +78,9 @@ class CRM_Mailing_Info extends CRM_Core_Component_Info { $result['crmMailingAB'] = array( 'ext' => 'civicrm', 'js' => array( - 'js/angular-crmMailingAB.js', + 'ang/crmMailingAB.js', + 'ang/crmMailingAB/*.js', + 'ang/crmMailingAB/*/*.js', 'js/angular-crmMailingAB/*.js', ), 'css' => array('css/angular-crmMailingAB.css'), diff --git a/ang/crmMailingAB.js b/ang/crmMailingAB.js new file mode 100644 index 0000000000..684c19cc20 --- /dev/null +++ b/ang/crmMailingAB.js @@ -0,0 +1,44 @@ +(function(angular, $, _) { + + angular.module('crmMailingAB', ['ngRoute', 'ui.utils', 'crmUi', 'crmAttachment', 'crmMailing', 'crmD3']); + angular.module('crmMailingAB').config([ + '$routeProvider', + function($routeProvider) { + $routeProvider.when('/abtest', { + templateUrl: '~/crmMailingAB/ListCtrl.html', + controller: 'CrmMailingABListCtrl', + resolve: { + mailingABList: function($route, crmApi) { + return crmApi('MailingAB', 'get', {rowCount: 0}); + }, + fields: function(crmMetadata) { + return crmMetadata.getFields('MailingAB'); + } + } + }); + $routeProvider.when('/abtest/new', { + template: '

' + ts('Initializing...') + '

', + controller: 'CrmMailingABNewCtrl', + resolve: { + abtest: function($route, CrmMailingAB) { + var abtest = new CrmMailingAB(null); + return abtest.load().then(function() { + return abtest.save(); + }); + } + } + }); + $routeProvider.when('/abtest/:id', { + templateUrl: '~/crmMailingAB/EditCtrl/main.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(); + } + } + }); + } + ]); + +})(angular, CRM.$, CRM._); diff --git a/ang/crmMailingAB/EditCtrl.js b/ang/crmMailingAB/EditCtrl.js new file mode 100644 index 0000000000..914280125c --- /dev/null +++ b/ang/crmMailingAB/EditCtrl.js @@ -0,0 +1,144 @@ +(function(angular, $, _) { + + angular.module('crmMailingAB').controller('CrmMailingABEditCtrl', function($scope, abtest, crmMailingABCriteria, crmMailingMgr, crmMailingPreviewMgr, crmStatus, $q, $location, crmBlocker, $interval, $timeout, CrmAutosaveCtrl, dialogService) { + $scope.abtest = abtest; + var ts = $scope.ts = CRM.ts(null); + var block = $scope.block = crmBlocker(); + $scope.crmUrl = CRM.url; + var myAutosave = null; + $scope.crmMailingABCriteria = crmMailingABCriteria; + $scope.crmMailingConst = CRM.crmMailing; + $scope.checkPerm = CRM.checkPerm; + + $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('Final (%1)', {1: abtest.ab.name}); + + if (abtest.ab.testing_criteria) { + // TODO review fields exposed in UI and make sure the sync rules match + switch (abtest.ab.testing_criteria) { + case 'subject': + crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [ + 'name', + 'recipients', + 'subject' + ]); + break; + case 'from': + crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [ + 'name', + 'recipients', + 'from_name', + 'from_email' + ]); + break; + case 'full_email': + crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [ + 'name', + 'recipients', + 'subject', + 'from_name', + 'from_email', + 'replyto_email', + 'override_verp', // keep override_verp and replyto_Email linked + 'body_html', + 'body_text' + ]); + break; + default: + throw "Unrecognized testing_criteria"; + } + } + crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings.a, ['name']); + return true; + }; + + // @return Promise + $scope.save = function save() { + return block(crmStatus({start: ts('Saving...'), success: ts('Saved')}, abtest.save())); + }; + + // @return Promise + $scope.previewMailing = function previewMailing(mailingName, mode) { + return crmMailingPreviewMgr.preview(abtest.mailings[mailingName], mode); + }; + + // @return Promise + $scope.sendTest = function sendTest(mailingName, recipient) { + return block(crmStatus({start: ts('Saving...'), success: ''}, abtest.save()) + .then(function() { + crmMailingPreviewMgr.sendTest(abtest.mailings[mailingName], recipient); + })); + }; + + // @return Promise + $scope.delete = function() { + return block(crmStatus({start: ts('Deleting...'), success: ts('Deleted')}, abtest.delete().then($scope.leave))); + }; + + // @return Promise + $scope.submit = function submit() { + if (block.check() || $scope.crmMailingAB.$invalid) { + return; + } + return block(crmStatus({start: ts('Saving...'), success: ''}, abtest.save()) + .then(function() { + return crmStatus({ + start: ts('Submitting...'), + success: ts('Submitted') + }, myAutosave.suspend(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()...) + }) + ); + }; + + $scope.leave = function leave() { + $location.path('abtest'); + $location.replace(); + }; + + $scope.selectWinner = function selectWinner(mailingName) { + var model = { + abtest: $scope.abtest, + mailingName: mailingName + }; + var options = CRM.utils.adjustDialogDefaults({ + autoOpen: false, + height: 'auto', + width: '40%', + title: ts('Select Final Mailing (Test %1)', { + 1: mailingName.toUpperCase() + }) + }); + return myAutosave.suspend(dialogService.open('selectWinnerDialog', '~/crmMailingAB/WinnerDialogCtrl.html', model, options)); + }; + + // initialize + var syncJob = $interval($scope.sync, 333); + $scope.$on('$destroy', function() { + $interval.cancel(syncJob); + }); + + myAutosave = new CrmAutosaveCtrl({ + save: $scope.save, + saveIf: function() { + return abtest.ab.status == 'Draft' && $scope.sync(); + }, + model: function() { + return abtest.getAutosaveSignature(); + }, + form: function() { + return $scope.crmMailingAB; + } + }); + $timeout(myAutosave.start); + $scope.$on('$destroy', myAutosave.stop); + }); + +})(angular, CRM.$, CRM._); diff --git a/ang/crmMailingAB/ListCtrl.js b/ang/crmMailingAB/ListCtrl.js new file mode 100644 index 0000000000..d0ced773a2 --- /dev/null +++ b/ang/crmMailingAB/ListCtrl.js @@ -0,0 +1,12 @@ +(function(angular, $, _) { + + angular.module('crmMailingAB').controller('CrmMailingABListCtrl', function($scope, mailingABList, crmMailingABCriteria, crmMailingABStatus, fields) { + var ts = $scope.ts = CRM.ts(null); + $scope.mailingABList = _.values(mailingABList.values); + $scope.crmMailingABCriteria = crmMailingABCriteria; + $scope.crmMailingABStatus = crmMailingABStatus; + $scope.fields = fields; + $scope.filter = {}; + }); + +})(angular, CRM.$, CRM._); diff --git a/ang/crmMailingAB/NewCtrl.js b/ang/crmMailingAB/NewCtrl.js new file mode 100644 index 0000000000..edcfa70519 --- /dev/null +++ b/ang/crmMailingAB/NewCtrl.js @@ -0,0 +1,11 @@ +(function(angular, $, _) { + + angular.module('crmMailingAB').controller('CrmMailingABNewCtrl', function($scope, abtest, $location) { + // Transition URL "/abtest/new/foo" => "/abtest/123/foo" + var parts = $location.path().split('/'); // e.g. "/mailing/new" or "/mailing/123/wizard" + parts[2] = abtest.id; + $location.path(parts.join('/')); + $location.replace(); + }); + +})(angular, CRM.$, CRM._); diff --git a/ang/crmMailingAB/ReportCtrl.js b/ang/crmMailingAB/ReportCtrl.js new file mode 100644 index 0000000000..9f44db9755 --- /dev/null +++ b/ang/crmMailingAB/ReportCtrl.js @@ -0,0 +1,52 @@ +(function(angular, $, _) { + + angular.module('crmMailingAB').controller('CrmMailingABReportCtrl', function($scope, crmApi, crmMailingStats) { + var ts = $scope.ts = CRM.ts(null); + + var CrmMailingABReportCnt = 1, activeMailings = null; + $scope.getActiveMailings = function() { + if ($scope.abtest.$CrmMailingABReportCnt != CrmMailingABReportCnt) { + $scope.abtest.$CrmMailingABReportCnt = ++CrmMailingABReportCnt; + activeMailings = [ + { + name: 'a', + title: ts('Mailing A'), + mailing: $scope.abtest.mailings.a, + attachments: $scope.abtest.attachments.a + }, + { + name: 'b', + title: ts('Mailing B'), + mailing: $scope.abtest.mailings.b, + attachments: $scope.abtest.attachments.b + } + ]; + if ($scope.abtest.ab.status == 'Final') { + activeMailings.push({ + name: 'c', + title: ts('Final'), + mailing: $scope.abtest.mailings.c, + attachments: $scope.abtest.attachments.c + }); + } + } + return activeMailings; + }; + + crmMailingStats.getStats({ + a: $scope.abtest.ab.mailing_id_a, + b: $scope.abtest.ab.mailing_id_b, + c: $scope.abtest.ab.mailing_id_c + }).then(function(stats) { + $scope.stats = stats; + }); + + $scope.statTypes = crmMailingStats.getStatTypes(); + $scope.statUrl = function statUrl(mailing, statType, view) { + return crmMailingStats.getUrl(mailing, statType, view, 'abtest/' + $scope.abtest.ab.id); + }; + + $scope.checkPerm = CRM.checkPerm; + }); + +})(angular, CRM.$, CRM._); diff --git a/ang/crmMailingAB/WinnerDialogCtrl.js b/ang/crmMailingAB/WinnerDialogCtrl.js new file mode 100644 index 0000000000..b5bd3bf63c --- /dev/null +++ b/ang/crmMailingAB/WinnerDialogCtrl.js @@ -0,0 +1,52 @@ +(function(angular, $, _) { + + angular.module('crmMailingAB').controller('CrmMailingABWinnerDialogCtrl', function($scope, $timeout, dialogService, crmMailingMgr, crmStatus) { + var ts = $scope.ts = CRM.ts(null); + 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 = [ + { + text: ts('Submit final mailing'), + icons: {primary: 'ui-icon-check'}, + click: function() { + crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings[mailingName], [ + 'name', + 'recipients', + 'scheduled_date' + ]); + crmStatus({start: ts('Saving...'), success: ''}, abtest.save()) + .then(function() { + return crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, + abtest.submitFinal().then(function(r) { + delete abtest.$CrmMailingABReportCnt; + return r; + })); + }) + .then(function() { + dialogService.close('selectWinnerDialog', abtest); + }); + } + }, + { + text: ts('Cancel'), + icons: {primary: 'ui-icon-close'}, + click: function() { + dialogService.cancel('selectWinnerDialog'); + } + } + ]; + dialogService.setButtons('selectWinnerDialog', buttons); + } + + $timeout(init); + }); + +})(angular, CRM.$, CRM._); diff --git a/js/angular-crmMailingAB.js b/js/angular-crmMailingAB.js deleted file mode 100644 index cd94cbbde4..0000000000 --- a/js/angular-crmMailingAB.js +++ /dev/null @@ -1,282 +0,0 @@ -(function (angular, $, _) { - - angular.module('crmMailingAB', ['ngRoute', 'ui.utils', 'crmUi', 'crmAttachment', 'crmMailing', 'crmD3']); - angular.module('crmMailingAB').config([ - '$routeProvider', - function ($routeProvider) { - $routeProvider.when('/abtest', { - templateUrl: '~/crmMailingAB/ListCtrl.html', - controller: 'CrmMailingABListCtrl', - resolve: { - mailingABList: function ($route, crmApi) { - return crmApi('MailingAB', 'get', {rowCount: 0}); - }, - fields: function(crmMetadata){ - return crmMetadata.getFields('MailingAB'); - } - } - }); - $routeProvider.when('/abtest/new', { - template: '

' + ts('Initializing...') + '

', - controller: 'CrmMailingABNewCtrl', - resolve: { - abtest: function ($route, CrmMailingAB) { - var abtest = new CrmMailingAB(null); - return abtest.load().then(function(){ - return abtest.save(); - }); - } - } - }); - $routeProvider.when('/abtest/:id', { - templateUrl: '~/crmMailingAB/EditCtrl/main.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(); - } - } - }); - } - ]); - - angular.module('crmMailingAB').controller('CrmMailingABListCtrl', function($scope, mailingABList, crmMailingABCriteria, crmMailingABStatus, fields) { - var ts = $scope.ts = CRM.ts(null); - $scope.mailingABList = _.values(mailingABList.values); - $scope.crmMailingABCriteria = crmMailingABCriteria; - $scope.crmMailingABStatus = crmMailingABStatus; - $scope.fields = fields; - $scope.filter = {}; - }); - - angular.module('crmMailingAB').controller('CrmMailingABNewCtrl', function ($scope, abtest, $location) { - // Transition URL "/abtest/new/foo" => "/abtest/123/foo" - var parts = $location.path().split('/'); // e.g. "/mailing/new" or "/mailing/123/wizard" - parts[2] = abtest.id; - $location.path(parts.join('/')); - $location.replace(); - }); - - angular.module('crmMailingAB').controller('CrmMailingABEditCtrl', function ($scope, abtest, crmMailingABCriteria, crmMailingMgr, crmMailingPreviewMgr, crmStatus, $q, $location, crmBlocker, $interval, $timeout, CrmAutosaveCtrl, dialogService) { - $scope.abtest = abtest; - var ts = $scope.ts = CRM.ts(null); - var block = $scope.block = crmBlocker(); - $scope.crmUrl = CRM.url; - var myAutosave = null; - $scope.crmMailingABCriteria = crmMailingABCriteria; - $scope.crmMailingConst = CRM.crmMailing; - $scope.checkPerm = CRM.checkPerm; - - $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('Final (%1)', {1: abtest.ab.name}); - - if (abtest.ab.testing_criteria) { - // TODO review fields exposed in UI and make sure the sync rules match - switch (abtest.ab.testing_criteria) { - case 'subject': - crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [ - 'name', - 'recipients', - 'subject' - ]); - break; - case 'from': - crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [ - 'name', - 'recipients', - 'from_name', - 'from_email' - ]); - break; - case 'full_email': - crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [ - 'name', - 'recipients', - 'subject', - 'from_name', - 'from_email', - 'replyto_email', - 'override_verp', // keep override_verp and replyto_Email linked - 'body_html', - 'body_text' - ]); - break; - default: - throw "Unrecognized testing_criteria"; - } - } - crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings.a, ['name']); - return true; - }; - - // @return Promise - $scope.save = function save() { - return block(crmStatus({start: ts('Saving...'), success: ts('Saved')}, abtest.save())); - }; - - // @return Promise - $scope.previewMailing = function previewMailing(mailingName, mode) { - return crmMailingPreviewMgr.preview(abtest.mailings[mailingName], mode); - }; - - // @return Promise - $scope.sendTest = function sendTest(mailingName, recipient) { - return block(crmStatus({start: ts('Saving...'), success: ''}, abtest.save()) - .then(function () { - crmMailingPreviewMgr.sendTest(abtest.mailings[mailingName], recipient); - })); - }; - - // @return Promise - $scope.delete = function () { - return block(crmStatus({start: ts('Deleting...'), success: ts('Deleted')}, abtest.delete().then($scope.leave))); - }; - - // @return Promise - $scope.submit = function submit() { - if (block.check() || $scope.crmMailingAB.$invalid) { - return; - } - return block(crmStatus({start: ts('Saving...'), success: ''}, abtest.save()) - .then(function() { - return crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, myAutosave.suspend(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()...) - }) - ); - }; - - $scope.leave = function leave() { - $location.path('abtest'); - $location.replace(); - }; - - $scope.selectWinner = function selectWinner(mailingName) { - var model = { - abtest: $scope.abtest, - mailingName: mailingName - }; - var options = CRM.utils.adjustDialogDefaults({ - autoOpen: false, - height: 'auto', - width: '40%', - title: ts('Select Final Mailing (Test %1)', { - 1: mailingName.toUpperCase() - }) - }); - return myAutosave.suspend(dialogService.open('selectWinnerDialog', '~/crmMailingAB/WinnerDialogCtrl.html', model, options)); - }; - - // initialize - var syncJob = $interval($scope.sync, 333); - $scope.$on('$destroy', function(){ - $interval.cancel(syncJob); - }); - - myAutosave = new CrmAutosaveCtrl({ - save: $scope.save, - saveIf: function(){ - return abtest.ab.status == 'Draft' && $scope.sync(); - }, - model: function(){ - return abtest.getAutosaveSignature(); - }, - form: function() { - return $scope.crmMailingAB; - } - }); - $timeout(myAutosave.start); - $scope.$on('$destroy', myAutosave.stop); - }); - - angular.module('crmMailingAB').controller('CrmMailingABReportCtrl', function ($scope, crmApi, crmMailingStats) { - var ts = $scope.ts = CRM.ts(null); - - var CrmMailingABReportCnt = 1, activeMailings = null; - $scope.getActiveMailings = function() { - if ($scope.abtest.$CrmMailingABReportCnt != CrmMailingABReportCnt) { - $scope.abtest.$CrmMailingABReportCnt = ++CrmMailingABReportCnt; - activeMailings = [ - {name: 'a', title: ts('Mailing A'), mailing: $scope.abtest.mailings.a, attachments: $scope.abtest.attachments.a}, - {name: 'b', title: ts('Mailing B'), mailing: $scope.abtest.mailings.b, attachments: $scope.abtest.attachments.b} - ]; - if ($scope.abtest.ab.status == 'Final') { - activeMailings.push({name: 'c', title: ts('Final'), mailing: $scope.abtest.mailings.c, attachments: $scope.abtest.attachments.c}); - } - } - return activeMailings; - }; - - crmMailingStats.getStats({ - a: $scope.abtest.ab.mailing_id_a, - b: $scope.abtest.ab.mailing_id_b, - c: $scope.abtest.ab.mailing_id_c - }).then(function(stats) { - $scope.stats = stats; - }); - - $scope.statTypes = crmMailingStats.getStatTypes(); - $scope.statUrl = function statUrl(mailing, statType, view) { - return crmMailingStats.getUrl(mailing, statType, view, 'abtest/' + $scope.abtest.ab.id); - }; - - $scope.checkPerm = CRM.checkPerm; - }); - - angular.module('crmMailingAB').controller('CrmMailingABWinnerDialogCtrl', function ($scope, $timeout, dialogService, crmMailingMgr, crmStatus) { - var ts = $scope.ts = CRM.ts(null); - 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 = [ - { - text: ts('Submit final mailing'), - icons: {primary: 'ui-icon-check'}, - click: function () { - crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings[mailingName], [ - 'name', - 'recipients', - 'scheduled_date' - ]); - crmStatus({start: ts('Saving...'), success: ''}, abtest.save()) - .then(function () { - return crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, - abtest.submitFinal().then(function(r){ - delete abtest.$CrmMailingABReportCnt; - return r; - })); - }) - .then(function(){ - dialogService.close('selectWinnerDialog', abtest); - }); - } - }, - { - text: ts('Cancel'), - icons: {primary: 'ui-icon-close'}, - click: function () { - dialogService.cancel('selectWinnerDialog'); - } - } - ]; - dialogService.setButtons('selectWinnerDialog', buttons); - } - - $timeout(init); - }); - -})(angular, CRM.$, CRM._); -- 2.25.1