CRM-15578 - crmMailing2 - When ID of new mailing is established, update navbar.
[civicrm-core.git] / js / angular-crmMailing2.js
1 (function (angular, $, _) {
2 var partialUrl = function partialUrl(relPath) {
3 return CRM.resourceUrls['civicrm'] + '/partials/crmMailing2/' + relPath;
4 };
5
6 var crmMailing2 = angular.module('crmMailing2', ['ngRoute', 'ui.utils', 'crmUi', 'dialogService']); // TODO ngSanitize, unsavedChanges
7
8 // Time to wait before triggering AJAX update to recipients list
9 var RECIPIENTS_DEBOUNCE_MS = 100;
10 var RECIPIENTS_PREVIEW_LIMIT = 10000;
11
12 crmMailing2.config(['$routeProvider',
13 function ($routeProvider) {
14 $routeProvider.when('/mailing2', {
15 template: '<div></div>',
16 controller: 'ListMailingsCtrl'
17 });
18 $routeProvider.when('/mailing2/:id', {
19 templateUrl: partialUrl('edit.html'),
20 controller: 'EditMailingCtrl',
21 resolve: {
22 selectedMail: function selectedMail($route, crmMailingMgr) { return crmMailingMgr.getOrCreate($route.current.params.id); }
23 }
24 });
25 $routeProvider.when('/mailing2/:id/unified', {
26 templateUrl: partialUrl('edit-unified.html'),
27 controller: 'EditMailingCtrl',
28 resolve: {
29 selectedMail: function selectedMail($route, crmMailingMgr) { return crmMailingMgr.getOrCreate($route.current.params.id); }
30 }
31 });
32 $routeProvider.when('/mailing2/:id/unified2', {
33 templateUrl: partialUrl('edit-unified2.html'),
34 controller: 'EditMailingCtrl',
35 resolve: {
36 selectedMail: function selectedMail($route, crmMailingMgr) { return crmMailingMgr.getOrCreate($route.current.params.id); }
37 }
38 });
39 $routeProvider.when('/mailing2/:id/wizard', {
40 templateUrl: partialUrl('edit-wizard.html'),
41 controller: 'EditMailingCtrl',
42 resolve: {
43 selectedMail: function selectedMail($route, crmMailingMgr) { return crmMailingMgr.getOrCreate($route.current.params.id); }
44 }
45 });
46 }
47 ]);
48
49 crmMailing2.controller('ListMailingsCtrl', function ListMailingsCtrl($scope) {
50 // We haven't implemented this in Angular, but some users may get clever
51 // about typing URLs, so we'll provide a redirect.
52 window.location = CRM.url('civicrm/mailing/browse/unscheduled', {
53 reset: 1,
54 scheduled: 'false'
55 });
56 });
57
58 crmMailing2.controller('EditMailingCtrl', function EditMailingCtrl($scope, selectedMail, $location) {
59 $scope.mailing = selectedMail;
60 $scope.crmMailingConst = CRM.crmMailing;
61
62 $scope.partialUrl = partialUrl;
63 $scope.ts = CRM.ts('CiviMail');
64
65 $scope.send = function() {
66 CRM.alert('Send!');
67 };
68 $scope.save = function() {
69 CRM.alert('Save!');
70 };
71 $scope.cancel = function() {
72 CRM.alert('Cancel!');
73 };
74 $scope.leave = function() {
75 window.location = CRM.url('civicrm/mailing/browse/unscheduled', {
76 reset: 1,
77 scheduled: 'false'
78 });
79 };
80
81 // Transition URL "/mailing2/new" => "/mailing2/123" as soon as ID is known
82 $scope.$watch('mailing.id', function(newValue, oldValue) {
83 if (newValue && newValue != oldValue) {
84 var parts = $location.path().split('/'); // e.g. "/mailing2/new" or "/mailing2/123/wizard"
85 parts[2] = newValue;
86 $location.path(parts.join('/'));
87 $location.replace();
88 // FIXME: Angular unnecessarily refreshes UI
89 }
90 });
91 });
92
93 // Controller for the edit-recipients fields (
94 // WISHLIST: Move most of this to a (cache-enabled) service
95 // Scope members:
96 // - [input] mailing: object
97 // - [output] recipients: array of recipient records
98 crmMailing2.controller('EditRecipCtrl', function EditRecipCtrl($scope, dialogService, crmApi, crmMailingMgr) {
99 // TODO load & live update real recipients list
100 $scope.recipients = null;
101 $scope.getRecipientsEstimate = function () {
102 var ts = $scope.ts;
103 if ($scope.recipients == null)
104 return ts('(Estimating)');
105 if ($scope.recipients.length == 0)
106 return ts('No recipients');
107 if ($scope.recipients.length == 1)
108 return ts('~1 recipient');
109 if (RECIPIENTS_PREVIEW_LIMIT > 0 && $scope.recipients.length >= RECIPIENTS_PREVIEW_LIMIT)
110 return ts('>%1 recipients', {1: RECIPIENTS_PREVIEW_LIMIT});
111 return ts('~%1 recipients', {1: $scope.recipients.length});
112 };
113 // We monitor four fields -- use debounce so that changes across the
114 // four fields can settle-down before AJAX.
115 var refreshRecipients = _.debounce(function () {
116 $scope.$apply(function () {
117 $scope.recipients = null;
118 crmMailingMgr.previewRecipients($scope.mailing, RECIPIENTS_PREVIEW_LIMIT).then(function (recipients) {
119 $scope.recipients = recipients;
120 });
121 });
122 }, RECIPIENTS_DEBOUNCE_MS);
123 $scope.$watchCollection("mailing.groups.include", refreshRecipients);
124 $scope.$watchCollection("mailing.groups.exclude", refreshRecipients);
125 $scope.$watchCollection("mailing.mailings.include", refreshRecipients);
126 $scope.$watchCollection("mailing.mailings.exclude", refreshRecipients);
127
128 $scope.previewRecipients = function previewRecipients() {
129 var model = {
130 recipients: $scope.recipients
131 };
132 var options = {
133 autoOpen: false,
134 modal: true,
135 title: ts('Preview (%1)', {
136 1: $scope.getRecipientsEstimate()
137 }),
138 };
139 dialogService.open('recipDialog', partialUrl('dialog/recipients.html'), model, options);
140 };
141 });
142
143 // Controller for the "Preview Recipients" dialog
144 // Note: Expects $scope.model to be an object with properties:
145 // - recipients: array of contacts
146 crmMailing2.controller('PreviewRecipCtrl', function ($scope) {
147 $scope.ts = CRM.ts('CiviMail');
148 });
149
150 // Controller for the "Preview Mailing" segment
151 // Note: Expects $scope.model to be an object with properties:
152 // - mailing: object
153 crmMailing2.controller('PreviewMailingCtrl', function ($scope, dialogService, crmMailingMgr) {
154 $scope.ts = CRM.ts('CiviMail');
155 $scope.testContact = {email: CRM.crmMailing.defaultTestEmail};
156 $scope.testGroup = {gid: null};
157
158 $scope.previewHtml = function previewHtml() {
159 $scope.previewDialog(partialUrl('dialog/previewHtml.html'));
160 };
161 $scope.previewText = function previewText() {
162 $scope.previewDialog(partialUrl('dialog/previewText.html'));
163 };
164 $scope.previewFull = function previewFull() {
165 $scope.previewDialog(partialUrl('dialog/previewFull.html'));
166 };
167 // Open a dialog with a preview of the current mailing
168 // @param template string URL of the template to use in the preview dialog
169 $scope.previewDialog = function previewDialog(template) {
170 var p = crmMailingMgr
171 .preview($scope.mailing)
172 .then(function(content){
173 var options = {
174 autoOpen: false,
175 modal: true,
176 title: ts('Subject: %1', {
177 1: content.subject
178 })
179 };
180 dialogService.open('previewDialog', template, content, options);
181 });
182 CRM.status({start: ts('Previewing'), success: ''}, CRM.toJqPromise(p));
183 };
184 $scope.sendTestToContact = function sendTestToContact() {
185 $scope.sendTest($scope.mailing, $scope.testContact.email, null);
186 };
187 $scope.sendTestToGroup = function sendTestToGroup() {
188 $scope.sendTest($scope.mailing, null, $scope.testGroup.gid);
189 };
190 $scope.sendTest = function sendTest(mailing, testEmail, testGroup) {
191 var promise = crmMailingMgr.sendTest(mailing, testEmail, testGroup).then(function(deliveryInfos){
192 var count = Object.keys(deliveryInfos).length;
193 if (count === 0) {
194 CRM.alert(ts('Could not identify any recipients. Perhaps the group is empty?'));
195 }
196 });
197 CRM.status({
198 start: ts('Sending...'),
199 success: ts('Sent')
200 }, CRM.toJqPromise(promise));
201 };
202 });
203
204 // Controller for the "Preview Mailing" dialog
205 // Note: Expects $scope.model to be an object with properties:
206 // - "subject"
207 // - "body_html"
208 // - "body_text"
209 crmMailing2.controller('PreviewMailingDialogCtrl', function PreviewMailingDialogCtrl($scope, crmMailingMgr) {
210 $scope.ts = CRM.ts('CiviMail');
211 });
212
213 })(angular, CRM.$, CRM._);