Multiple Angular modules - Remove partialUrl() helper
[civicrm-core.git] / js / angular-crmMailingAB.js
1 (function (angular, $, _) {
2
3 angular.module('crmMailingAB', ['ngRoute', 'ui.utils', 'ngSanitize', 'crmUi', 'crmAttachment', 'crmMailing', 'crmD3']);
4 angular.module('crmMailingAB').config([
5 '$routeProvider',
6 function ($routeProvider) {
7 $routeProvider.when('/abtest', {
8 templateUrl: '~/crmMailingAB/list.html',
9 controller: 'CrmMailingABListCtrl',
10 resolve: {
11 mailingABList: function ($route, crmApi) {
12 return crmApi('MailingAB', 'get', {rowCount: 0});
13 }
14 }
15 });
16 $routeProvider.when('/abtest/:id', {
17 templateUrl: '~/crmMailingAB/edit.html',
18 controller: 'CrmMailingABEditCtrl',
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 });
26 $routeProvider.when('/abtest/:id/report', {
27 templateUrl: '~/crmMailingAB/report.html',
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 });
36 }
37 ]);
38
39 angular.module('crmMailingAB').controller('CrmMailingABListCtrl', function ($scope, mailingABList, crmMailingABCriteria, crmMailingABStatus) {
40 var ts = $scope.ts = CRM.ts(null);
41 $scope.mailingABList = mailingABList.values;
42 $scope.crmMailingABCriteria = crmMailingABCriteria;
43 $scope.crmMailingABStatus = crmMailingABStatus;
44 });
45
46 angular.module('crmMailingAB').controller('CrmMailingABEditCtrl', function ($scope, abtest, crmMailingABCriteria, crmMailingMgr, crmMailingPreviewMgr, crmStatus, $q, $location) {
47 $scope.abtest = abtest;
48 var ts = $scope.ts = CRM.ts(null);
49 $scope.crmMailingABCriteria = crmMailingABCriteria;
50 $scope.crmMailingConst = CRM.crmMailing;
51
52 $scope.isSubmitted = function isSubmitted() {
53 return _.size(abtest.mailings.a.jobs) > 0 || _.size(abtest.mailings.b.jobs) > 0;
54 };
55
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) {
63 // TODO review fields exposed in UI and make sure the sync rules match
64 switch (criteria.name) {
65 case 'Subject lines':
66 crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [
67 'name',
68 'groups',
69 'mailings',
70 'subject'
71 ]);
72 break;
73 case 'From names':
74 crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [
75 'name',
76 'groups',
77 'mailings',
78 'from_name',
79 'from_email'
80 ]);
81 break;
82 case 'Two different emails':
83 crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [
84 'name',
85 'groups',
86 'mailings',
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']);
99 return $q.when(true);
100 };
101
102 // @return Promise
103 $scope.save = function save() {
104 $scope.sync();
105 return crmStatus({start: ts('Saving...'), success: ts('Saved')}, abtest.save().then(updateUrl));
106 };
107
108 // @return Promise
109 $scope.previewMailing = function previewMailing(mailingName, mode) {
110 $scope.sync();
111 return crmMailingPreviewMgr.preview(abtest.mailings[mailingName], mode);
112 };
113
114 // @return Promise
115 $scope.sendTest = function sendTest(mailingName, recipient) {
116 $scope.sync();
117 return crmStatus({start: ts('Saving...'), success: ''}, abtest.save().then(updateUrl))
118 .then(function () {
119 crmMailingPreviewMgr.sendTest(abtest.mailings[mailingName], recipient);
120 });
121 };
122
123 // @return Promise
124 $scope.delete = function () {
125 return crmStatus({start: ts('Deleting...'), success: ts('Deleted')}, abtest.delete().then(leave));
126 };
127
128 // @return Promise
129 $scope.submit = function submit() {
130 $scope.sync();
131 return crmStatus({start: ts('Saving...'), success: ''}, abtest.save())
132 .then(function () {
133 return crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, abtest.submitTest());
134 // Note: We're going to leave, so we don't care that submit() modifies several server-side records.
135 // If we stayed on this page, then we'd care about updating and call: abtest.submitTest().then(...abtest.load()...)
136 })
137 .then(leave);
138 };
139
140 function leave() {
141 $location.path('abtest');
142 $location.replace();
143 }
144
145 function updateCriteriaName() {
146 var criteria = crmMailingABCriteria.get($scope.abtest.ab.testing_criteria_id);
147 $scope.criteriaName = criteria ? criteria.name : null;
148 }
149
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
163 // initialize
164 updateCriteriaName();
165 $scope.sync();
166 $scope.$watch('abtest.ab.testing_criteria_id', updateCriteriaName);
167 });
168
169 angular.module('crmMailingAB').controller('CrmMailingABReportCtrl', function ($scope, abtest, crmApi, crmMailingPreviewMgr, dialogService) {
170 var ts = $scope.ts = CRM.ts(null);
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 });
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 };
200 return dialogService.open('selectWinnerDialog', '~/crmMailingAB/selectWinner.html', model, options);
201 };
202 });
203
204
205 angular.module('crmMailingAB').controller('CrmMailingABWinnerDialogCtrl', function ($scope, $timeout, dialogService, crmMailingMgr, crmStatus) {
206 var ts = $scope.ts = CRM.ts(null);
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);
243 });
244
245 })(angular, CRM.$, CRM._);