CRM-15578 - crmMailing(AB) - Submission & status tracking
[civicrm-core.git] / js / angular-crmMailingAB.js
1 (function (angular, $, _) {
2
3 var partialUrl = function (relPath, module) {
4 if (!module) {
5 module = 'crmMailingAB';
6 }
7 return CRM.resourceUrls['civicrm'] + '/partials/' + module + '/' + relPath;
8 };
9
10 angular.module('crmMailingAB', ['ngRoute', 'ui.utils', 'ngSanitize', 'crmUi', 'crmAttachment', 'crmMailing']);
11 angular.module('crmMailingAB').config([
12 '$routeProvider',
13 function ($routeProvider) {
14 $routeProvider.when('/abtest', {
15 templateUrl: partialUrl('list.html'),
16 controller: 'CrmMailingABListCtrl',
17 resolve: {
18 mailingABList: function ($route, crmApi) {
19 return crmApi('MailingAB', 'get', {rowCount: 0});
20 }
21 }
22 });
23 $routeProvider.when('/abtest/:id', {
24 templateUrl: partialUrl('edit.html'),
25 controller: 'CrmMailingABEditCtrl',
26 resolve: {
27 abtest: function ($route, CrmMailingAB) {
28 var abtest = new CrmMailingAB($route.current.params.id == 'new' ? null : $route.current.params.id);
29 return abtest.load();
30 }
31 }
32 });
33 }
34 ]);
35
36 angular.module('crmMailingAB').controller('CrmMailingABListCtrl', function ($scope, mailingABList, crmMailingABCriteria) {
37 $scope.mailingABList = mailingABList.values;
38 $scope.testing_criteria = crmMailingABCriteria.getAll();
39 });
40
41 angular.module('crmMailingAB').controller('CrmMailingABEditCtrl', function ($scope, abtest, crmMailingABCriteria, crmMailingMgr, crmMailingPreviewMgr, crmStatus, $q, $location) {
42 $scope.abtest = abtest;
43 var ts = $scope.ts = CRM.ts('CiviMail');
44 $scope.crmMailingABCriteria = crmMailingABCriteria;
45 $scope.crmMailingConst = CRM.crmMailing;
46 $scope.partialUrl = partialUrl;
47
48 $scope.isSubmitted = function isSubmitted() {
49 return _.size(abtest.mailings.a.jobs) > 0 || _.size(abtest.mailings.b.jobs) > 0;
50 };
51 $scope.sync = function sync() {
52 abtest.mailings.a.name = ts('Test A (%1)', {1: abtest.ab.name});
53 abtest.mailings.b.name = ts('Test B (%1)', {1: abtest.ab.name});
54 abtest.mailings.c.name = ts('Winner (%1)', {1: abtest.ab.name});
55
56 var criteria = crmMailingABCriteria.get(abtest.ab.testing_criteria_id);
57 if (criteria) {
58 // TODO review fields exposed in UI and make sure the sync rules match
59 switch (criteria.name) {
60 case 'Subject lines':
61 crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, ['name', 'subject']);
62 break;
63 case 'From names':
64 crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, ['name', 'from_name', 'from_email']);
65 break;
66 case 'Two different emails':
67 crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [
68 'name',
69 'subject',
70 'from_name',
71 'from_email',
72 'body_html',
73 'body_text'
74 ]);
75 break;
76 default:
77 throw "Unrecognized testing_criteria";
78 }
79 }
80 crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings.a, ['name']);
81 };
82
83 // @return Promise
84 $scope.save = function save() {
85 $scope.sync();
86 return crmStatus({start: ts('Saving...'), success: ts('Saved')}, abtest.save().then(updateUrl));
87 };
88
89 // @return Promise
90 $scope.previewMailing = function previewMailing(mailingName, mode) {
91 return crmMailingPreviewMgr.preview(abtest.mailings[mailingName], mode);
92 };
93
94 // @return Promise
95 $scope.sendTest = function sendTest(mailingName, recipient) {
96 return crmStatus({start: ts('Saving...'), success: ''}, abtest.save().then(updateUrl))
97 .then(function () {
98 crmMailingPreviewMgr.sendTest(abtest.mailings[mailingName], recipient);
99 });
100 };
101
102 // @return Promise
103 $scope.delete = function () {
104 return crmStatus({start: ts('Deleting...'), success: ts('Deleted')}, abtest.delete());
105 };
106
107 // @return Promise
108 $scope.submit = function submit() {
109 return crmStatus({start: ts('Saving...'), success: ''}, abtest.save().then(updateUrl))
110 .then(function () {
111 return crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, $q.all([
112 crmMailingMgr.submit(abtest.mailings.a),
113 crmMailingMgr.submit(abtest.mailings.b)
114 ]));
115 });
116 };
117
118 function updateCriteriaName() {
119 var criteria = crmMailingABCriteria.get($scope.abtest.ab.testing_criteria_id)
120 $scope.criteriaName = criteria ? criteria.name : null;
121 }
122
123 // Transition URL "/abtest/new" => "/abtest/123"
124 function updateUrl() {
125 var parts = $location.path().split('/'); // e.g. "/abtest/new" or "/abtest/123/wizard"
126 if (parts[2] != $scope.abtest.ab.id) {
127 parts[2] = $scope.abtest.ab.id;
128 $location.path(parts.join('/'));
129 $location.replace();
130 // FIXME: Angular unnecessarily refreshes UI
131 // WARNING: Changing the URL triggers a full reload. Any pending AJAX operations
132 // could be inconsistently applied. Run updateUrl() after other changes complete.
133 }
134 }
135
136 // initialize
137 updateCriteriaName();
138 $scope.sync();
139 $scope.$watch('abtest.ab.testing_criteria_id', updateCriteriaName);
140 });
141
142 })(angular, CRM.$, CRM._);