Merge pull request #5174 from joannechester/patch-2
[civicrm-core.git] / js / angular-crmMailingAB.js
CommitLineData
70980d8e
TO
1(function (angular, $, _) {
2
360aaa75 3 angular.module('crmMailingAB', ['ngRoute', 'ui.utils', 'ngSanitize', 'crmUi', 'crmAttachment', 'crmMailing', 'crmD3']);
efd95528 4 angular.module('crmMailingAB').config([
70980d8e
TO
5 '$routeProvider',
6 function ($routeProvider) {
efd95528 7 $routeProvider.when('/abtest', {
ef5d18a1 8 templateUrl: '~/crmMailingAB/list.html',
efd95528 9 controller: 'CrmMailingABListCtrl',
70980d8e
TO
10 resolve: {
11 mailingABList: function ($route, crmApi) {
12 return crmApi('MailingAB', 'get', {rowCount: 0});
13 }
14 }
15 });
a12bd71d
TO
16 $routeProvider.when('/abtest/new', {
17 template: '<p>' + ts('Initializing...') + '</p>',
18 controller: 'CrmMailingABNewCtrl',
19 resolve: {
20 abtest: function ($route, CrmMailingAB) {
21 var abtest = new CrmMailingAB(null);
22 return abtest.load().then(function(){
23 return abtest.save();
24 });
25 }
26 }
27 });
efd95528 28 $routeProvider.when('/abtest/:id', {
ef5d18a1 29 templateUrl: '~/crmMailingAB/edit.html',
efd95528 30 controller: 'CrmMailingABEditCtrl',
70980d8e
TO
31 resolve: {
32 abtest: function ($route, CrmMailingAB) {
33 var abtest = new CrmMailingAB($route.current.params.id == 'new' ? null : $route.current.params.id);
34 return abtest.load();
35 }
36 }
37 });
360aaa75 38 $routeProvider.when('/abtest/:id/report', {
ef5d18a1 39 templateUrl: '~/crmMailingAB/report.html',
360aaa75
TO
40 controller: 'CrmMailingABReportCtrl',
41 resolve: {
42 abtest: function ($route, CrmMailingAB) {
43 var abtest = new CrmMailingAB($route.current.params.id);
44 return abtest.load();
45 }
46 }
47 });
70980d8e
TO
48 }
49 ]);
50
63430d3c 51 angular.module('crmMailingAB').controller('CrmMailingABListCtrl', function ($scope, mailingABList, crmMailingABCriteria, crmMailingABStatus) {
5d8901af 52 var ts = $scope.ts = CRM.ts(null);
70980d8e 53 $scope.mailingABList = mailingABList.values;
63430d3c
TO
54 $scope.crmMailingABCriteria = crmMailingABCriteria;
55 $scope.crmMailingABStatus = crmMailingABStatus;
a7931384 56 });
70980d8e 57
a12bd71d
TO
58 angular.module('crmMailingAB').controller('CrmMailingABNewCtrl', function ($scope, abtest, $location) {
59 // Transition URL "/abtest/new/foo" => "/abtest/123/foo"
60 var parts = $location.path().split('/'); // e.g. "/mailing/new" or "/mailing/123/wizard"
61 parts[2] = abtest.id;
62 $location.path(parts.join('/'));
63 $location.replace();
64 });
65
ce245e83 66 angular.module('crmMailingAB').controller('CrmMailingABEditCtrl', function ($scope, abtest, crmMailingABCriteria, crmMailingMgr, crmMailingPreviewMgr, crmStatus, $q, $location, crmBlocker, $interval) {
70980d8e 67 $scope.abtest = abtest;
5d8901af 68 var ts = $scope.ts = CRM.ts(null);
a12bd71d 69 var block = $scope.block = crmBlocker();
af6962d8 70 $scope.crmMailingABCriteria = crmMailingABCriteria;
bcdd7f49 71 $scope.crmMailingConst = CRM.crmMailing;
af6962d8 72
86c3a327
TO
73 $scope.isSubmitted = function isSubmitted() {
74 return _.size(abtest.mailings.a.jobs) > 0 || _.size(abtest.mailings.b.jobs) > 0;
75 };
c9e9a71e 76
70980d8e
TO
77 $scope.sync = function sync() {
78 abtest.mailings.a.name = ts('Test A (%1)', {1: abtest.ab.name});
79 abtest.mailings.b.name = ts('Test B (%1)', {1: abtest.ab.name});
80 abtest.mailings.c.name = ts('Winner (%1)', {1: abtest.ab.name});
81
82 var criteria = crmMailingABCriteria.get(abtest.ab.testing_criteria_id);
83 if (criteria) {
d3b6424f 84 // TODO review fields exposed in UI and make sure the sync rules match
70980d8e
TO
85 switch (criteria.name) {
86 case 'Subject lines':
c9e9a71e
TO
87 crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [
88 'name',
9cd4f489 89 'recipients',
c9e9a71e
TO
90 'subject'
91 ]);
70980d8e
TO
92 break;
93 case 'From names':
c9e9a71e
TO
94 crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [
95 'name',
9cd4f489 96 'recipients',
c9e9a71e
TO
97 'from_name',
98 'from_email'
99 ]);
70980d8e
TO
100 break;
101 case 'Two different emails':
102 crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [
103 'name',
9cd4f489 104 'recipients',
70980d8e
TO
105 'subject',
106 'from_name',
107 'from_email',
495f197a
TO
108 'replyto_email',
109 'override_verp', // keep override_verp and replyto_Email linked
70980d8e
TO
110 'body_html',
111 'body_text'
112 ]);
113 break;
114 default:
115 throw "Unrecognized testing_criteria";
116 }
117 }
118 crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings.a, ['name']);
ce245e83 119 return true;
70980d8e 120 };
86c3a327
TO
121
122 // @return Promise
70980d8e 123 $scope.save = function save() {
80e64ffc 124 return block(crmStatus({start: ts('Saving...'), success: ts('Saved')}, abtest.save()));
58dfba8d 125 };
86c3a327 126
58dfba8d
TO
127 // @return Promise
128 $scope.previewMailing = function previewMailing(mailingName, mode) {
129 return crmMailingPreviewMgr.preview(abtest.mailings[mailingName], mode);
130 };
131
132 // @return Promise
133 $scope.sendTest = function sendTest(mailingName, recipient) {
80e64ffc 134 return block(crmStatus({start: ts('Saving...'), success: ''}, abtest.save())
58dfba8d
TO
135 .then(function () {
136 crmMailingPreviewMgr.sendTest(abtest.mailings[mailingName], recipient);
a12bd71d 137 }));
70980d8e 138 };
86c3a327
TO
139
140 // @return Promise
70980d8e 141 $scope.delete = function () {
a12bd71d 142 return block(crmStatus({start: ts('Deleting...'), success: ts('Deleted')}, abtest.delete().then($scope.leave)));
70980d8e 143 };
86c3a327
TO
144
145 // @return Promise
146 $scope.submit = function submit() {
ce245e83 147 if (block.check() || $scope.crmMailingAB.$invalid) {
a12bd71d
TO
148 return;
149 }
150 return block(crmStatus({start: ts('Saving...'), success: ''}, abtest.save())
151 .then(function() {
152 return crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, abtest.submitTest());
153 // Note: We're going to leave, so we don't care that submit() modifies several server-side records.
154 // If we stayed on this page, then we'd care about updating and call: abtest.submitTest().then(...abtest.load()...)
155 })
ce245e83 156 ).then($scope.leave);
22bc3e48
TO
157 };
158
a12bd71d 159 $scope.leave = function leave() {
b0797ac3
TO
160 $location.path('abtest');
161 $location.replace();
a12bd71d 162 };
b0797ac3 163
22bc3e48 164 function updateCriteriaName() {
f2bad133 165 var criteria = crmMailingABCriteria.get($scope.abtest.ab.testing_criteria_id);
bcdd7f49 166 $scope.criteriaName = criteria ? criteria.name : null;
22bc3e48 167 }
70980d8e 168
22bc3e48
TO
169 // initialize
170 updateCriteriaName();
22bc3e48 171 $scope.$watch('abtest.ab.testing_criteria_id', updateCriteriaName);
ce245e83
TO
172 var syncJob = $interval($scope.sync, 333);
173 $scope.$on('$destroy', function(){
174 $interval.cancel(syncJob);
175 });
70980d8e
TO
176 });
177
32b8b0bf 178 angular.module('crmMailingAB').controller('CrmMailingABReportCtrl', function ($scope, abtest, crmApi, crmMailingPreviewMgr, dialogService) {
5d8901af 179 var ts = $scope.ts = CRM.ts(null);
360aaa75
TO
180
181 $scope.abtest = abtest;
182
183 $scope.stats = {};
184 crmApi('Mailing', 'stats', {mailing_id: abtest.ab.mailing_id_a}).then(function(data){
185 $scope.stats.a = data.values[abtest.ab.mailing_id_a];
186 });
187 crmApi('Mailing', 'stats', {mailing_id: abtest.ab.mailing_id_b}).then(function(data){
188 $scope.stats.b = data.values[abtest.ab.mailing_id_b];
189 });
32b8b0bf
TO
190 crmApi('Mailing', 'stats', {mailing_id: abtest.ab.mailing_id_c}).then(function(data){
191 $scope.stats.c = data.values[abtest.ab.mailing_id_c];
192 });
193
194 $scope.previewMailing = function previewMailing(mailingName, mode) {
195 return crmMailingPreviewMgr.preview(abtest.mailings[mailingName], mode);
196 };
197 $scope.selectWinner = function selectWinner(mailingName) {
198 var model = {
199 abtest: abtest,
200 mailingName: mailingName
201 };
b1fc510d 202 var options = CRM.utils.adjustDialogDefaults({
32b8b0bf 203 autoOpen: false,
32b8b0bf
TO
204 title: ts('Select Winner (%1)', {
205 1: mailingName.toUpperCase()
206 })
b1fc510d 207 });
ef5d18a1 208 return dialogService.open('selectWinnerDialog', '~/crmMailingAB/selectWinner.html', model, options);
32b8b0bf
TO
209 };
210 });
211
212
213 angular.module('crmMailingAB').controller('CrmMailingABWinnerDialogCtrl', function ($scope, $timeout, dialogService, crmMailingMgr, crmStatus) {
5d8901af 214 var ts = $scope.ts = CRM.ts(null);
32b8b0bf
TO
215 var abtest = $scope.abtest = $scope.model.abtest;
216 var mailingName = $scope.model.mailingName;
217
218 var titles = {a: ts('Mailing A'), b: ts('Mailing B')};
219 $scope.mailingTitle = titles[mailingName];
220
221 function init() {
222 // When using dialogService with a button bar, the major button actions
223 // need to be registered with the dialog widget (and not embedded in
224 // the body of the dialog).
225 var buttons = {};
226 buttons[ts('Select Winner')] = function () {
227 crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings[mailingName], [
228 'name',
9cd4f489 229 'recipients',
32b8b0bf
TO
230 'scheduled_date'
231 ]);
232 crmStatus({start: ts('Saving...'), success: ''}, abtest.save())
233 .then(function () {
234 return crmStatus({start: ts('Submitting...'), success: ts('Submitted')},
235 abtest.submitFinal().then(function(){
236 return abtest.load();
237 }));
238 })
239 .then(function(){
240 dialogService.close('selectWinnerDialog', abtest);
241 });
242 };
243 buttons[ts('Cancel')] = function () {
244 dialogService.cancel('selectWinnerDialog');
245 };
246 dialogService.setButtons('selectWinnerDialog', buttons);
247 }
248
249 $timeout(init);
360aaa75
TO
250 });
251
70980d8e 252})(angular, CRM.$, CRM._);