Commit | Line | Data |
---|---|---|
030dce01 | 1 | (function (angular, $, _) { |
030dce01 | 2 | |
88e9e883 | 3 | angular.module('crmMailing', [ |
8443385d | 4 | 'crmUtil', 'crmAttachment', 'crmAutosave', 'ngRoute', 'ui.utils', 'crmUi', 'dialogService' |
f4f103fa | 5 | ]); // TODO ngSanitize, unsavedChanges |
030dce01 | 6 | |
7801d9b5 TO |
7 | // Time to wait before triggering AJAX update to recipients list |
8 | var RECIPIENTS_DEBOUNCE_MS = 100; | |
b73e0c53 | 9 | var RECIPIENTS_PREVIEW_LIMIT = 10000; |
7801d9b5 | 10 | |
88e9e883 | 11 | angular.module('crmMailing').config([ |
f4f103fa | 12 | '$routeProvider', |
030dce01 | 13 | function ($routeProvider) { |
96ac27bd | 14 | $routeProvider.when('/mailing', { |
030dce01 TO |
15 | template: '<div></div>', |
16 | controller: 'ListMailingsCtrl' | |
17 | }); | |
b7c3beb2 TO |
18 | |
19 | var editorPaths = { | |
ef5d18a1 TO |
20 | '': '~/crmMailing/edit.html', |
21 | '/unified': '~/crmMailing/edit-unified.html', | |
22 | '/unified2': '~/crmMailing/edit-unified2.html', | |
23 | '/wizard': '~/crmMailing/edit-wizard.html' | |
b7c3beb2 TO |
24 | }; |
25 | angular.forEach(editorPaths, function(editTemplate, pathSuffix) { | |
26 | $routeProvider.when('/mailing/new' + pathSuffix, { | |
27 | template: '<p>' + ts('Initializing...') + '</p>', | |
28 | controller: 'CreateMailingCtrl', | |
29 | resolve: { | |
30 | selectedMail: function(crmMailingMgr) { | |
31 | var m = crmMailingMgr.create(); | |
32 | return crmMailingMgr.save(m); | |
33 | } | |
f4f103fa | 34 | } |
b7c3beb2 TO |
35 | }); |
36 | $routeProvider.when('/mailing/:id' + pathSuffix, { | |
37 | templateUrl: editTemplate, | |
38 | controller: 'EditMailingCtrl', | |
39 | resolve: { | |
40 | selectedMail: function($route, crmMailingMgr) { | |
41 | return crmMailingMgr.get($route.current.params.id); | |
f2cdd789 TO |
42 | }, |
43 | attachments: function($route, CrmAttachments) { | |
44 | var attachments = new CrmAttachments(function () { | |
45 | return {entity_table: 'civicrm_mailing', entity_id: $route.current.params.id}; | |
46 | }); | |
47 | return attachments.load(); | |
b7c3beb2 | 48 | } |
f4f103fa | 49 | } |
b7c3beb2 | 50 | }); |
030dce01 TO |
51 | }); |
52 | } | |
53 | ]); | |
54 | ||
416abe87 | 55 | angular.module('crmMailing').controller('ListMailingsCtrl', ['crmLegacy', 'crmNavigator', function ListMailingsCtrl(crmLegacy, crmNavigator) { |
030dce01 TO |
56 | // We haven't implemented this in Angular, but some users may get clever |
57 | // about typing URLs, so we'll provide a redirect. | |
416abe87 PH |
58 | var new_url = crmLegacy.url('civicrm/mailing/browse/unscheduled', {reset: 1, scheduled: 'false'}); |
59 | crmNavigator.redirect(new_url); | |
60 | }]); | |
030dce01 | 61 | |
b7c3beb2 TO |
62 | angular.module('crmMailing').controller('CreateMailingCtrl', function EditMailingCtrl($scope, selectedMail, $location) { |
63 | // Transition URL "/mailing/new/foo" => "/mailing/123/foo" | |
64 | var parts = $location.path().split('/'); // e.g. "/mailing/new" or "/mailing/123/wizard" | |
65 | parts[2] = selectedMail.id; | |
66 | $location.path(parts.join('/')); | |
67 | $location.replace(); | |
68 | }); | |
69 | ||
f2cdd789 | 70 | angular.module('crmMailing').controller('EditMailingCtrl', function EditMailingCtrl($scope, selectedMail, $location, crmMailingMgr, crmStatus, attachments, crmMailingPreviewMgr, crmBlocker) { |
27e690c2 | 71 | $scope.mailing = selectedMail; |
f2cdd789 | 72 | $scope.attachments = attachments; |
27e690c2 TO |
73 | $scope.crmMailingConst = CRM.crmMailing; |
74 | ||
5d8901af | 75 | var ts = $scope.ts = CRM.ts(null); |
bdd3f781 | 76 | var block = $scope.block = crmBlocker(); |
27e690c2 | 77 | |
86c3a327 TO |
78 | $scope.isSubmitted = function isSubmitted() { |
79 | return _.size($scope.mailing.jobs) > 0; | |
80 | }; | |
81 | ||
58dfba8d TO |
82 | // @return Promise |
83 | $scope.previewMailing = function previewMailing(mailing, mode) { | |
84 | return crmMailingPreviewMgr.preview(mailing, mode); | |
85 | }; | |
86 | ||
87 | // @return Promise | |
88 | $scope.sendTest = function sendTest(mailing, attachments, recipient) { | |
89 | var savePromise = crmMailingMgr.save(mailing) | |
90 | .then(function () { | |
91 | return attachments.save(); | |
b7c3beb2 | 92 | }); |
bdd3f781 | 93 | return block(crmStatus({start: ts('Saving...'), success: ''}, savePromise) |
58dfba8d TO |
94 | .then(function () { |
95 | crmMailingPreviewMgr.sendTest(mailing, recipient); | |
bdd3f781 | 96 | })); |
58dfba8d TO |
97 | }; |
98 | ||
705c61e9 TO |
99 | // @return Promise |
100 | $scope.submit = function submit() { | |
c9ae63bb TO |
101 | if (block.check() || $scope.crmMailing.$invalid) { |
102 | return; | |
103 | } | |
104 | ||
db083bf0 | 105 | var promise = crmMailingMgr.save($scope.mailing) |
86c3a327 TO |
106 | .then(function () { |
107 | // pre-condition: the mailing exists *before* saving attachments to it | |
108 | return $scope.attachments.save(); | |
109 | }) | |
110 | .then(function () { | |
111 | return crmMailingMgr.submit($scope.mailing); | |
112 | }) | |
113 | .then(function () { | |
650a6ffc | 114 | $scope.leave('scheduled'); |
86c3a327 TO |
115 | }) |
116 | ; | |
bdd3f781 | 117 | return block(crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, promise)); |
2d36e6bc | 118 | }; |
58dfba8d | 119 | |
705c61e9 TO |
120 | // @return Promise |
121 | $scope.save = function save() { | |
bdd3f781 | 122 | return block(crmStatus(null, |
db083bf0 TO |
123 | crmMailingMgr |
124 | .save($scope.mailing) | |
125 | .then(function () { | |
126 | // pre-condition: the mailing exists *before* saving attachments to it | |
127 | return $scope.attachments.save(); | |
128 | }) | |
bdd3f781 | 129 | )); |
2d36e6bc | 130 | }; |
58dfba8d | 131 | |
705c61e9 TO |
132 | // @return Promise |
133 | $scope.delete = function cancel() { | |
bdd3f781 | 134 | return block(crmStatus({start: ts('Deleting...'), success: ts('Deleted')}, |
f286acec | 135 | crmMailingMgr.delete($scope.mailing) |
b0797ac3 | 136 | .then(function () { |
650a6ffc | 137 | $scope.leave('unscheduled'); |
b0797ac3 | 138 | }) |
bdd3f781 | 139 | )); |
2d36e6bc | 140 | }; |
58dfba8d | 141 | |
b0797ac3 | 142 | // @param string listingScreen 'archive', 'scheduled', 'unscheduled' |
650a6ffc | 143 | $scope.leave = function leave(listingScreen) { |
b0797ac3 TO |
144 | switch (listingScreen) { |
145 | case 'archive': | |
146 | window.location = CRM.url('civicrm/mailing/browse/archived', { | |
147 | reset: 1 | |
148 | }); | |
149 | break; | |
150 | case 'scheduled': | |
151 | window.location = CRM.url('civicrm/mailing/browse/scheduled', { | |
152 | reset: 1, | |
153 | scheduled: 'true' | |
154 | }); | |
155 | break; | |
156 | case 'unscheduled': | |
8acf0123 | 157 | /* falls through */ |
b0797ac3 TO |
158 | default: |
159 | window.location = CRM.url('civicrm/mailing/browse/unscheduled', { | |
160 | reset: 1, | |
161 | scheduled: 'false' | |
162 | }); | |
163 | } | |
650a6ffc | 164 | }; |
030dce01 TO |
165 | }); |
166 | ||
7801d9b5 TO |
167 | // Controller for the edit-recipients fields ( |
168 | // WISHLIST: Move most of this to a (cache-enabled) service | |
169 | // Scope members: | |
170 | // - [input] mailing: object | |
171 | // - [output] recipients: array of recipient records | |
08baf3ec | 172 | angular.module('crmMailing').controller('EditRecipCtrl', function EditRecipCtrl($scope, dialogService, crmApi, crmMailingMgr, $q, crmMetadata) { |
5d8901af | 173 | var ts = $scope.ts = CRM.ts(null); |
7801d9b5 TO |
174 | $scope.recipients = null; |
175 | $scope.getRecipientsEstimate = function () { | |
176 | var ts = $scope.ts; | |
8acf0123 | 177 | if ($scope.recipients === null) { |
7801d9b5 | 178 | return ts('(Estimating)'); |
f4f103fa | 179 | } |
8acf0123 | 180 | if ($scope.recipients.length === 0) { |
7801d9b5 | 181 | return ts('No recipients'); |
f4f103fa | 182 | } |
8acf0123 | 183 | if ($scope.recipients.length === 1) { |
7801d9b5 | 184 | return ts('~1 recipient'); |
f4f103fa TO |
185 | } |
186 | if (RECIPIENTS_PREVIEW_LIMIT > 0 && $scope.recipients.length >= RECIPIENTS_PREVIEW_LIMIT) { | |
b73e0c53 | 187 | return ts('>%1 recipients', {1: RECIPIENTS_PREVIEW_LIMIT}); |
f4f103fa | 188 | } |
7801d9b5 TO |
189 | return ts('~%1 recipients', {1: $scope.recipients.length}); |
190 | }; | |
f4f103fa | 191 | $scope.getIncludesAsString = function () { |
47bacc20 TO |
192 | var first = true; |
193 | var names = ''; | |
9cd4f489 | 194 | _.each($scope.mailing.recipients.groups.include, function (id) { |
f4f103fa TO |
195 | if (!first) { |
196 | names = names + ', '; | |
197 | } | |
198 | var group = _.where(CRM.crmMailing.groupNames, {id: '' + id}); | |
47bacc20 TO |
199 | names = names + group[0].title; |
200 | first = false; | |
201 | }); | |
9cd4f489 | 202 | _.each($scope.mailing.recipients.mailings.include, function (id) { |
f4f103fa TO |
203 | if (!first) { |
204 | names = names + ', '; | |
205 | } | |
206 | var oldMailing = _.where(CRM.crmMailing.civiMails, {id: '' + id}); | |
47bacc20 TO |
207 | names = names + oldMailing[0].name; |
208 | first = false; | |
209 | }); | |
210 | return names; | |
211 | }; | |
f4f103fa | 212 | $scope.getExcludesAsString = function () { |
47bacc20 TO |
213 | var first = true; |
214 | var names = ''; | |
9cd4f489 | 215 | _.each($scope.mailing.recipients.groups.exclude, function (id) { |
f4f103fa TO |
216 | if (!first) { |
217 | names = names + ', '; | |
218 | } | |
219 | var group = _.where(CRM.crmMailing.groupNames, {id: '' + id}); | |
47bacc20 TO |
220 | names = names + group[0].title; |
221 | first = false; | |
222 | }); | |
9cd4f489 | 223 | _.each($scope.mailing.recipients.mailings.exclude, function (id) { |
f4f103fa TO |
224 | if (!first) { |
225 | names = names + ', '; | |
226 | } | |
227 | var oldMailing = _.where(CRM.crmMailing.civiMails, {id: '' + id}); | |
47bacc20 TO |
228 | names = names + oldMailing[0].name; |
229 | first = false; | |
230 | }); | |
231 | return names; | |
232 | }; | |
233 | ||
7801d9b5 TO |
234 | // We monitor four fields -- use debounce so that changes across the |
235 | // four fields can settle-down before AJAX. | |
236 | var refreshRecipients = _.debounce(function () { | |
237 | $scope.$apply(function () { | |
238 | $scope.recipients = null; | |
8dfd5110 TO |
239 | crmMailingMgr.previewRecipients($scope.mailing, RECIPIENTS_PREVIEW_LIMIT).then(function (recipients) { |
240 | $scope.recipients = recipients; | |
b73e0c53 | 241 | }); |
7801d9b5 TO |
242 | }); |
243 | }, RECIPIENTS_DEBOUNCE_MS); | |
9cd4f489 TO |
244 | $scope.$watchCollection("mailing.recipients.groups.include", refreshRecipients); |
245 | $scope.$watchCollection("mailing.recipients.groups.exclude", refreshRecipients); | |
246 | $scope.$watchCollection("mailing.recipients.mailings.include", refreshRecipients); | |
247 | $scope.$watchCollection("mailing.recipients.mailings.exclude", refreshRecipients); | |
7801d9b5 | 248 | |
4dd19229 | 249 | $scope.previewRecipients = function previewRecipients() { |
7801d9b5 TO |
250 | var model = { |
251 | recipients: $scope.recipients | |
252 | }; | |
b1fc510d | 253 | var options = CRM.utils.adjustDialogDefaults({ |
7801d9b5 | 254 | autoOpen: false, |
7801d9b5 TO |
255 | title: ts('Preview (%1)', { |
256 | 1: $scope.getRecipientsEstimate() | |
52f515c6 | 257 | }) |
b1fc510d | 258 | }); |
ef5d18a1 | 259 | dialogService.open('recipDialog', '~/crmMailing/dialog/recipients.html', model, options); |
7801d9b5 | 260 | }; |
b8b2e316 TO |
261 | |
262 | // Open a dialog for editing the advanced recipient options. | |
263 | $scope.editOptions = function editOptions(mailing) { | |
b1fc510d | 264 | var options = CRM.utils.adjustDialogDefaults({ |
b8b2e316 | 265 | autoOpen: false, |
b8b2e316 | 266 | title: ts('Edit Options') |
b1fc510d | 267 | }); |
08baf3ec TO |
268 | $q.when(crmMetadata.getFields('Mailing')).then(function(fields) { |
269 | var model = { | |
270 | fields: fields, | |
271 | mailing: mailing | |
272 | }; | |
273 | dialogService.open('previewComponentDialog', '~/crmMailing/dialog/recipientOptions.html', model, options); | |
274 | }); | |
b8b2e316 | 275 | }; |
7801d9b5 TO |
276 | }); |
277 | ||
278 | // Controller for the "Preview Recipients" dialog | |
279 | // Note: Expects $scope.model to be an object with properties: | |
280 | // - recipients: array of contacts | |
88e9e883 | 281 | angular.module('crmMailing').controller('PreviewRecipCtrl', function ($scope) { |
5d8901af | 282 | $scope.ts = CRM.ts(null); |
7801d9b5 | 283 | }); |
493eb47a | 284 | |
493eb47a TO |
285 | // Controller for the "Preview Mailing" dialog |
286 | // Note: Expects $scope.model to be an object with properties: | |
287 | // - "subject" | |
288 | // - "body_html" | |
289 | // - "body_text" | |
870cbdbb | 290 | angular.module('crmMailing').controller('PreviewMailingDialogCtrl', function PreviewMailingDialogCtrl($scope) { |
5d8901af | 291 | $scope.ts = CRM.ts(null); |
493eb47a TO |
292 | }); |
293 | ||
b8b2e316 | 294 | // Controller for the "Recipients: Edit Options" dialog |
3cf58cc3 TO |
295 | // Note: Expects $scope.model to be an object with properties: |
296 | // - "mailing" (APIv3 mailing object) | |
297 | // - "fields" (list of fields) | |
b8b2e316 TO |
298 | angular.module('crmMailing').controller('EditRecipOptionsDialogCtrl', function EditRecipOptionsDialogCtrl($scope) { |
299 | $scope.ts = CRM.ts(null); | |
300 | }); | |
301 | ||
47bacc20 TO |
302 | // Controller for the "Preview Mailing Component" segment |
303 | // which displays header/footer/auto-responder | |
d376f33e | 304 | angular.module('crmMailing').controller('PreviewComponentCtrl', function PreviewComponentCtrl($scope, dialogService) { |
5d8901af | 305 | var ts = $scope.ts = CRM.ts(null); |
52f515c6 | 306 | |
47bacc20 | 307 | $scope.previewComponent = function previewComponent(title, componentId) { |
f4f103fa | 308 | var component = _.where(CRM.crmMailing.headerfooterList, {id: "" + componentId}); |
47bacc20 TO |
309 | if (!component || !component[0]) { |
310 | CRM.alert(ts('Invalid component ID (%1)', { | |
311 | 1: componentId | |
312 | })); | |
313 | return; | |
314 | } | |
b1fc510d | 315 | var options = CRM.utils.adjustDialogDefaults({ |
47bacc20 | 316 | autoOpen: false, |
47bacc20 | 317 | title: title // component[0].name |
b1fc510d | 318 | }); |
ef5d18a1 | 319 | dialogService.open('previewComponentDialog', '~/crmMailing/dialog/previewComponent.html', component[0], options); |
47bacc20 TO |
320 | }; |
321 | }); | |
322 | ||
d376f33e | 323 | // Controller for the "Preview Mailing Component" dialog |
47bacc20 TO |
324 | // Note: Expects $scope.model to be an object with properties: |
325 | // - "name" | |
326 | // - "subject" | |
327 | // - "body_html" | |
328 | // - "body_text" | |
d376f33e | 329 | angular.module('crmMailing').controller('PreviewComponentDialogCtrl', function PreviewComponentDialogCtrl($scope) { |
5d8901af | 330 | $scope.ts = CRM.ts(null); |
47bacc20 TO |
331 | }); |
332 | ||
744bebee | 333 | // Controller for the in-place msg-template management |
870cbdbb | 334 | angular.module('crmMailing').controller('MsgTemplateCtrl', function MsgTemplateCtrl($scope, crmMsgTemplates, dialogService) { |
5d8901af | 335 | var ts = $scope.ts = CRM.ts(null); |
744bebee TO |
336 | $scope.crmMsgTemplates = crmMsgTemplates; |
337 | ||
338 | // @return Promise MessageTemplate (per APIv3) | |
74263d6b | 339 | $scope.saveTemplate = function saveTemplate(mailing) { |
744bebee | 340 | var model = { |
74263d6b | 341 | selected_id: mailing.msg_template_id, |
744bebee TO |
342 | tpl: { |
343 | msg_title: '', | |
74263d6b TO |
344 | msg_subject: mailing.subject, |
345 | msg_text: mailing.body_text, | |
346 | msg_html: mailing.body_html | |
744bebee TO |
347 | } |
348 | }; | |
b1fc510d | 349 | var options = CRM.utils.adjustDialogDefaults({ |
744bebee | 350 | autoOpen: false, |
744bebee | 351 | title: ts('Save Template') |
b1fc510d | 352 | }); |
ef5d18a1 | 353 | return dialogService.open('saveTemplateDialog', '~/crmMailing/dialog/saveTemplate.html', model, options) |
f4f103fa | 354 | .then(function (item) { |
74263d6b | 355 | mailing.msg_template_id = item.id; |
744bebee TO |
356 | return item; |
357 | }); | |
358 | }; | |
359 | ||
360 | // @param int id | |
361 | // @return Promise | |
74263d6b | 362 | $scope.loadTemplate = function loadTemplate(mailing, id) { |
744bebee | 363 | return crmMsgTemplates.get(id).then(function (tpl) { |
74263d6b TO |
364 | mailing.subject = tpl.msg_subject; |
365 | mailing.body_text = tpl.msg_text; | |
366 | mailing.body_html = tpl.msg_html; | |
744bebee TO |
367 | }); |
368 | }; | |
369 | }); | |
370 | ||
371 | // Controller for the "Save Message Template" dialog | |
372 | // Scope members: | |
373 | // - [input] "model": Object | |
374 | // - "selected_id": int | |
375 | // - "tpl": Object | |
376 | // - "msg_subject": string | |
377 | // - "msg_text": string | |
378 | // - "msg_html": string | |
88e9e883 | 379 | angular.module('crmMailing').controller('SaveMsgTemplateDialogCtrl', function SaveMsgTemplateDialogCtrl($scope, crmMsgTemplates, dialogService) { |
5d8901af | 380 | var ts = $scope.ts = CRM.ts(null); |
744bebee TO |
381 | $scope.saveOpt = {mode: '', newTitle: ''}; |
382 | $scope.selected = null; | |
383 | ||
384 | $scope.save = function save() { | |
385 | var tpl = _.extend({}, $scope.model.tpl); | |
386 | switch ($scope.saveOpt.mode) { | |
387 | case 'add': | |
388 | tpl.msg_title = $scope.saveOpt.newTitle; | |
389 | break; | |
390 | case 'update': | |
391 | tpl.id = $scope.selected.id; | |
392 | tpl.msg_title = $scope.selected.msg_title; | |
393 | break; | |
394 | default: | |
395 | throw 'SaveMsgTemplateDialogCtrl: Unrecognized mode: ' + $scope.saveOpt.mode; | |
396 | } | |
397 | return crmMsgTemplates.save(tpl) | |
398 | .then(function (item) { | |
399 | CRM.status(ts('Saved')); | |
400 | return item; | |
401 | }); | |
402 | }; | |
403 | ||
404 | function scopeApply(f) { | |
405 | return function () { | |
406 | var args = arguments; | |
407 | $scope.$apply(function () { | |
408 | f.apply(args); | |
409 | }); | |
410 | }; | |
411 | } | |
412 | ||
413 | function init() { | |
414 | crmMsgTemplates.get($scope.model.selected_id).then( | |
415 | function (tpl) { | |
416 | $scope.saveOpt.mode = 'update'; | |
417 | $scope.selected = tpl; | |
418 | }, | |
419 | function () { | |
420 | $scope.saveOpt.mode = 'add'; | |
421 | $scope.selected = null; | |
422 | } | |
423 | ); | |
424 | // When using dialogService with a button bar, the major button actions | |
425 | // need to be registered with the dialog widget (and not embedded in | |
426 | // the body of the dialog). | |
269d44f5 CW |
427 | var buttons = [ |
428 | { | |
429 | text: ts('Save'), | |
430 | icons: {primary: 'ui-icon-check'}, | |
431 | click: function () { | |
432 | $scope.save().then(function (item) { | |
433 | dialogService.close('saveTemplateDialog', item); | |
434 | }); | |
435 | } | |
436 | }, | |
437 | { | |
438 | text: ts('Cancel'), | |
439 | icons: {primary: 'ui-icon-close'}, | |
440 | click: function () { | |
441 | dialogService.cancel('saveTemplateDialog'); | |
442 | } | |
443 | } | |
444 | ]; | |
744bebee TO |
445 | dialogService.setButtons('saveTemplateDialog', buttons); |
446 | } | |
f4f103fa | 447 | |
744bebee TO |
448 | setTimeout(scopeApply(init), 0); |
449 | }); | |
2d06b3b6 | 450 | |
87391d86 TO |
451 | angular.module('crmMailing').controller('EmailAddrCtrl', function EmailAddrCtrl($scope, crmFromAddresses, crmUiAlert) { |
452 | var ts = CRM.ts(null); | |
453 | function changeAlert(winnerField, loserField) { | |
454 | crmUiAlert({ | |
455 | title: ts('Conflict'), | |
456 | text: ts('The "%1" option conflicts with the "%2" option. The "%2" option has been disabled.', { | |
457 | 1: winnerField, | |
458 | 2: loserField | |
459 | }) | |
460 | }); | |
461 | } | |
462 | ||
0a993c89 | 463 | $scope.crmFromAddresses = crmFromAddresses; |
87391d86 TO |
464 | $scope.checkReplyToChange = function checkReplyToChange(mailing) { |
465 | if (!_.isEmpty(mailing.replyto_email) && mailing.override_verp == '0') { | |
466 | mailing.override_verp = '1'; | |
16f12592 | 467 | changeAlert(ts('Reply-To'), ts('Track Replies')); |
87391d86 TO |
468 | } |
469 | }; | |
470 | $scope.checkVerpChange = function checkVerpChange(mailing) { | |
471 | if (!_.isEmpty(mailing.replyto_email) && mailing.override_verp == '0') { | |
472 | mailing.replyto_email = ''; | |
473 | changeAlert(ts('Track Replies'), ts('Reply-To')); | |
474 | } | |
475 | }; | |
0a993c89 | 476 | }); |
21fb26b8 TO |
477 | |
478 | var lastEmailTokenAlert = null; | |
89f476c4 | 479 | angular.module('crmMailing').controller('EmailBodyCtrl', function EmailBodyCtrl($scope, crmMailingMgr, crmUiAlert, $timeout) { |
21fb26b8 TO |
480 | var ts = CRM.ts(null); |
481 | ||
89f476c4 TO |
482 | // ex: if (!hasAllTokens(myMailing, 'body_text)) alert('Oh noes!'); |
483 | $scope.hasAllTokens = function hasAllTokens(mailing, field) { | |
21fb26b8 TO |
484 | return _.isEmpty(crmMailingMgr.findMissingTokens(mailing, field)); |
485 | }; | |
486 | ||
89f476c4 TO |
487 | // ex: checkTokens(myMailing, 'body_text', 'insert:body_text') |
488 | // ex: checkTokens(myMailing, '*') | |
489 | $scope.checkTokens = function checkTokens(mailing, field, insertEvent) { | |
21fb26b8 TO |
490 | if (lastEmailTokenAlert) { |
491 | lastEmailTokenAlert.close(); | |
492 | } | |
89f476c4 TO |
493 | var missing, insertable; |
494 | if (field == '*') { | |
495 | insertable = false; | |
496 | missing = angular.extend({}, | |
497 | crmMailingMgr.findMissingTokens(mailing, 'body_html'), | |
498 | crmMailingMgr.findMissingTokens(mailing, 'body_text') | |
499 | ); | |
500 | } else { | |
501 | insertable = !_.isEmpty(insertEvent); | |
502 | missing = crmMailingMgr.findMissingTokens(mailing, field); | |
503 | } | |
504 | if (!_.isEmpty(missing)) { | |
505 | lastEmailTokenAlert = crmUiAlert({ | |
506 | type: 'error', | |
507 | title: ts('Required tokens'), | |
508 | templateUrl: '~/crmMailing/dialog/tokenAlert.html', | |
509 | scope: angular.extend($scope.$new(), { | |
510 | insertable: insertable, | |
511 | insertToken: function(token) { | |
512 | $timeout(function(){ | |
513 | $scope.$broadcast(insertEvent, '{' + token + '}'); | |
514 | $timeout(function(){ | |
515 | checkTokens(mailing, field, insertEvent); | |
516 | }); | |
517 | }); | |
518 | }, | |
519 | missing: missing | |
520 | }) | |
21fb26b8 | 521 | }); |
21fb26b8 | 522 | } |
d03e0d13 | 523 | }; |
21fb26b8 | 524 | }); |
030dce01 | 525 | })(angular, CRM.$, CRM._); |