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