CRM-15578 - crmMailingAB - Submit UI
[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
52 $scope.sync = function sync() {
53 abtest.mailings.a.name = ts('Test A (%1)', {1: abtest.ab.name});
54 abtest.mailings.b.name = ts('Test B (%1)', {1: abtest.ab.name});
55 abtest.mailings.c.name = ts('Winner (%1)', {1: abtest.ab.name});
56
57 var criteria = crmMailingABCriteria.get(abtest.ab.testing_criteria_id);
58 if (criteria) {
59 // TODO review fields exposed in UI and make sure the sync rules match
60 switch (criteria.name) {
61 case 'Subject lines':
62 crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [
63 'name',
64 'groups',
65 'mailings',
66 'subject'
67 ]);
68 break;
69 case 'From names':
70 crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [
71 'name',
72 'groups',
73 'mailings',
74 'from_name',
75 'from_email'
76 ]);
77 break;
78 case 'Two different emails':
79 crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [
80 'name',
81 'groups',
82 'mailings',
83 'subject',
84 'from_name',
85 'from_email',
86 'body_html',
87 'body_text'
88 ]);
89 break;
90 default:
91 throw "Unrecognized testing_criteria";
92 }
93 }
94 crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings.a, ['name']);
95 return $q.when(true);
96 };
97
98 // @return Promise
99 $scope.save = function save() {
100 $scope.sync();
101 return crmStatus({start: ts('Saving...'), success: ts('Saved')}, abtest.save().then(updateUrl));
102 };
103
104 // @return Promise
105 $scope.previewMailing = function previewMailing(mailingName, mode) {
106 $scope.sync();
107 return crmMailingPreviewMgr.preview(abtest.mailings[mailingName], mode);
108 };
109
110 // @return Promise
111 $scope.sendTest = function sendTest(mailingName, recipient) {
112 $scope.sync();
113 return crmStatus({start: ts('Saving...'), success: ''}, abtest.save().then(updateUrl))
114 .then(function () {
115 crmMailingPreviewMgr.sendTest(abtest.mailings[mailingName], recipient);
116 });
117 };
118
119 // @return Promise
120 $scope.delete = function () {
121 return crmStatus({start: ts('Deleting...'), success: ts('Deleted')}, abtest.delete().then(leave));
122 };
123
124 // @return Promise
125 $scope.submit = function submit() {
126 $scope.sync();
127 return crmStatus({start: ts('Saving...'), success: ''}, abtest.save())
128 .then(function () {
129 return crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, abtest.submit('Testing'));
130 // Note: We're going to leave, so we don't care that submit() modifies several server-side records.
131 // If we stayed on this page, then we'd care about updating and call: abtest.submit().then(abtest.load)
132 })
133 .then(leave);
134 };
135
136 function leave() {
137 $location.path('abtest');
138 $location.replace();
139 }
140
141 function updateCriteriaName() {
142 var criteria = crmMailingABCriteria.get($scope.abtest.ab.testing_criteria_id)
143 $scope.criteriaName = criteria ? criteria.name : null;
144 }
145
146 // Transition URL "/abtest/new" => "/abtest/123"
147 function updateUrl() {
148 var parts = $location.path().split('/'); // e.g. "/abtest/new" or "/abtest/123/wizard"
149 if (parts[2] != $scope.abtest.ab.id) {
150 parts[2] = $scope.abtest.ab.id;
151 $location.path(parts.join('/'));
152 $location.replace();
153 // FIXME: Angular unnecessarily refreshes UI
154 // WARNING: Changing the URL triggers a full reload. Any pending AJAX operations
155 // could be inconsistently applied. Run updateUrl() after other changes complete.
156 }
157 }
158
159 // initialize
160 updateCriteriaName();
161 $scope.sync();
162 $scope.$watch('abtest.ab.testing_criteria_id', updateCriteriaName);
163 });
164
165 })(angular, CRM.$, CRM._);