(function (angular, $, _) {
- var partialUrl = function (relPath) {
- return CRM.resourceUrls['civicrm'] + '/partials/crmMailing/' + relPath;
- };
// The representation of from/reply-to addresses is inconsistent in the mailing data-model,
// so the UI must do some adaptation. The crmFromAddresses provides a richer way to slice/dice
// the available "From:" addrs. Records are like the underlying OptionValues -- but add "email"
// and "author".
angular.module('crmMailing').factory('crmFromAddresses', function ($q, crmApi) {
- var emailRegex = /^"(.*)" \<([^@\>]*@[^@\>]*)\>$/;
+ var emailRegex = /^"(.*)" <([^@>]*@[^@>]*)>$/;
var addrs = _.map(CRM.crmMailing.fromAddress, function (addr) {
var match = emailRegex.exec(addr.label);
return angular.extend({}, addr, {
});
function first(array) {
- return (array.length == 0) ? null : array[0];
+ return (array.length === 0) ? null : array[0];
}
return {
tpl.id = '' + response.id; //parseInt(response.id);
tpls.push(tpl);
}
- lastModifiedTpl = tpl
+ lastModifiedTpl = tpl;
return tpl;
});
},
create: function create() {
return {
jobs: {}, // {jobId: JobRecord}
- name: "revert this", // fixme
+ name: "",
campaign_id: null,
from_name: crmFromAddresses.getDefault().author,
from_email: crmFromAddresses.getDefault().email,
replyto_email: "",
- subject: "For {contact.display_name}", // fixme
- dedupe_email: "1",
- groups: {include: [2], exclude: [4]}, // fixme
+ subject: "",
+ groups: {include: [], exclude: []},
mailings: {include: [], exclude: []},
- body_html: "<b>Hello</b> {contact.display_name}", // fixme
- body_text: "Hello {contact.display_name}", // fixme
+ body_html: "",
+ body_text: "",
footer_id: null, // pickDefaultMailComponent('Footer'),
header_id: null, // pickDefaultMailComponent('Header'),
visibility: "Public Pages",
if (!_.contains(excludes, field)) {
mailingTgt[field] = mailingFrom[field];
}
- })
+ });
},
// @param mailing Object (per APIv3)
// To get list of recipients, we tentatively save the mailing and
// get the resulting recipients -- then rollback any changes.
var params = angular.extend({}, mailing, {
+ name: 'placeholder', // for previewing recipients on new, incomplete mailing
+ subject: 'placeholder', // for previewing recipients on new, incomplete mailing
options: {force_rollback: 1},
'api.mailing_job.create': 1, // note: exact match to API default
'api.MailingRecipients.get': {
// Save a (draft) mailing
// @param mailing Object (per APIv3)
// @return Promise
- save: function (mailing) {
+ save: function(mailing) {
var params = angular.extend({}, mailing, {
'api.mailing_job.create': 0 // note: exact match to API default
});
+ // Angular ngModel sometimes treats blank fields as undefined.
+ angular.forEach(mailing, function(value, key) {
+ if (value === undefined) {
+ mailing[key] = '';
+ }
+ });
+
// WORKAROUND: Mailing.create (aka CRM_Mailing_BAO_Mailing::create()) interprets scheduled_date
// as an *intent* to schedule and creates tertiary records. Saving a draft with a scheduled_date
// is therefore not allowed. Remove this after fixing Mailing.create's contract.
delete params.jobs;
- return crmApi('Mailing', 'create', params).then(function (result) {
+ return crmApi('Mailing', 'create', params).then(function(result) {
if (result.id && !mailing.id) {
mailing.id = result.id;
} // no rollback, so update mailing.id
// @return Promise
preview: function preview(mailing, mode) {
var templates = {
- html: partialUrl('dialog/previewHtml.html'),
- text: partialUrl('dialog/previewText.html'),
- full: partialUrl('dialog/previewFull.html')
+ html: '~/crmMailing/dialog/previewHtml.html',
+ text: '~/crmMailing/dialog/previewText.html',
+ full: '~/crmMailing/dialog/previewFull.html'
};
var result = null;
var p = crmMailingMgr