1 (function (angular
, $, _
) {
2 var partialUrl
= function partialUrl(relPath
) {
3 return CRM
.resourceUrls
['civicrm'] + '/partials/crmMailing2/' + relPath
;
6 var crmMailing2
= angular
.module('crmMailing2', ['ngRoute', 'ui.utils', 'crmUi', 'dialogService']); // TODO ngSanitize, unsavedChanges
8 // Time to wait before triggering AJAX update to recipients list
9 var RECIPIENTS_DEBOUNCE_MS
= 100;
10 var RECIPIENTS_PREVIEW_LIMIT
= 10000;
12 crmMailing2
.config(['$routeProvider',
13 function ($routeProvider
) {
14 $routeProvider
.when('/mailing2', {
15 template
: '<div></div>',
16 controller
: 'ListMailingsCtrl'
18 $routeProvider
.when('/mailing2/:id', {
19 templateUrl
: partialUrl('edit.html'),
20 controller
: 'EditMailingCtrl',
22 selectedMail
: function selectedMail($route
, crmMailingMgr
) { return crmMailingMgr
.getOrCreate($route
.current
.params
.id
); }
25 $routeProvider
.when('/mailing2/:id/unified', {
26 templateUrl
: partialUrl('edit-unified.html'),
27 controller
: 'EditMailingCtrl',
29 selectedMail
: function selectedMail($route
, crmMailingMgr
) { return crmMailingMgr
.getOrCreate($route
.current
.params
.id
); }
32 $routeProvider
.when('/mailing2/:id/unified2', {
33 templateUrl
: partialUrl('edit-unified2.html'),
34 controller
: 'EditMailingCtrl',
36 selectedMail
: function selectedMail($route
, crmMailingMgr
) { return crmMailingMgr
.getOrCreate($route
.current
.params
.id
); }
39 $routeProvider
.when('/mailing2/:id/wizard', {
40 templateUrl
: partialUrl('edit-wizard.html'),
41 controller
: 'EditMailingCtrl',
43 selectedMail
: function selectedMail($route
, crmMailingMgr
) { return crmMailingMgr
.getOrCreate($route
.current
.params
.id
); }
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', {
58 crmMailing2
.controller('EditMailingCtrl', function EditMailingCtrl($scope
, selectedMail
, $location
) {
59 $scope
.mailing
= selectedMail
;
60 $scope
.crmMailingConst
= CRM
.crmMailing
;
62 $scope
.partialUrl
= partialUrl
;
63 $scope
.ts
= CRM
.ts('CiviMail');
65 $scope
.send = function() {
68 $scope
.save = function() {
71 $scope
.cancel = function() {
74 $scope
.leave = function() {
75 window
.location
= CRM
.url('civicrm/mailing/browse/unscheduled', {
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"
86 $location
.path(parts
.join('/'));
88 // FIXME: Angular unnecessarily refreshes UI
93 // Controller for the edit-recipients fields (
94 // WISHLIST: Move most of this to a (cache-enabled) service
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 () {
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
});
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
;
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
);
128 $scope
.previewRecipients
= function previewRecipients() {
130 recipients
: $scope
.recipients
135 title
: ts('Preview (%1)', {
136 1: $scope
.getRecipientsEstimate()
139 dialogService
.open('recipDialog', partialUrl('dialog/recipients.html'), model
, options
);
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');
150 // Controller for the "Preview Mailing" segment
151 // Note: Expects $scope.model to be an object with properties:
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};
158 $scope
.previewHtml
= function previewHtml() {
159 $scope
.previewDialog(partialUrl('dialog/previewHtml.html'));
161 $scope
.previewText
= function previewText() {
162 $scope
.previewDialog(partialUrl('dialog/previewText.html'));
164 $scope
.previewFull
= function previewFull() {
165 $scope
.previewDialog(partialUrl('dialog/previewFull.html'));
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
){
176 title
: ts('Subject: %1', {
180 dialogService
.open('previewDialog', template
, content
, options
);
182 CRM
.status({start
: ts('Previewing'), success
: ''}, CRM
.toJqPromise(p
));
184 $scope
.sendTestToContact
= function sendTestToContact() {
185 $scope
.sendTest($scope
.mailing
, $scope
.testContact
.email
, null);
187 $scope
.sendTestToGroup
= function sendTestToGroup() {
188 $scope
.sendTest($scope
.mailing
, null, $scope
.testGroup
.gid
);
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
;
194 CRM
.alert(ts('Could not identify any recipients. Perhaps the group is empty?'));
198 start
: ts('Sending...'),
200 }, CRM
.toJqPromise(promise
));
204 // Controller for the "Preview Mailing" dialog
205 // Note: Expects $scope.model to be an object with properties:
209 crmMailing2
.controller('PreviewMailingDialogCtrl', function PreviewMailingDialogCtrl($scope
, crmMailingMgr
) {
210 $scope
.ts
= CRM
.ts('CiviMail');
213 })(angular
, CRM
.$, CRM
._
);