From 9cd4f4894ba54a6970bb8d9e7b0c9001d99330df Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Wed, 11 Feb 2015 13:47:54 -0800 Subject: [PATCH] CRM-15856 - crmMailingRecipients - Use ngModel. Merge mailing.groups and mailing.mailings under mailing.recipients --- js/angular-crmMailing.js | 16 +++++----- js/angular-crmMailing/directives.js | 47 ++++++++++++++--------------- js/angular-crmMailing/services.js | 30 +++++++++++------- js/angular-crmMailingAB.js | 12 +++----- partials/crmMailing/recipients.html | 2 +- 5 files changed, 54 insertions(+), 53 deletions(-) diff --git a/js/angular-crmMailing.js b/js/angular-crmMailing.js index 889f8af88a..ed5321d7b0 100644 --- a/js/angular-crmMailing.js +++ b/js/angular-crmMailing.js @@ -191,7 +191,7 @@ $scope.getIncludesAsString = function () { var first = true; var names = ''; - _.each($scope.mailing.groups.include, function (id) { + _.each($scope.mailing.recipients.groups.include, function (id) { if (!first) { names = names + ', '; } @@ -199,7 +199,7 @@ names = names + group[0].title; first = false; }); - _.each($scope.mailing.mailings.include, function (id) { + _.each($scope.mailing.recipients.mailings.include, function (id) { if (!first) { names = names + ', '; } @@ -212,7 +212,7 @@ $scope.getExcludesAsString = function () { var first = true; var names = ''; - _.each($scope.mailing.groups.exclude, function (id) { + _.each($scope.mailing.recipients.groups.exclude, function (id) { if (!first) { names = names + ', '; } @@ -220,7 +220,7 @@ names = names + group[0].title; first = false; }); - _.each($scope.mailing.mailings.exclude, function (id) { + _.each($scope.mailing.recipients.mailings.exclude, function (id) { if (!first) { names = names + ', '; } @@ -241,10 +241,10 @@ }); }); }, RECIPIENTS_DEBOUNCE_MS); - $scope.$watchCollection("mailing.groups.include", refreshRecipients); - $scope.$watchCollection("mailing.groups.exclude", refreshRecipients); - $scope.$watchCollection("mailing.mailings.include", refreshRecipients); - $scope.$watchCollection("mailing.mailings.exclude", refreshRecipients); + $scope.$watchCollection("mailing.recipients.groups.include", refreshRecipients); + $scope.$watchCollection("mailing.recipients.groups.exclude", refreshRecipients); + $scope.$watchCollection("mailing.recipients.mailings.include", refreshRecipients); + $scope.$watchCollection("mailing.recipients.mailings.exclude", refreshRecipients); $scope.previewRecipients = function previewRecipients() { var model = { diff --git a/js/angular-crmMailing/directives.js b/js/angular-crmMailing/directives.js index dd80fa324d..d86fed8cfa 100644 --- a/js/angular-crmMailing/directives.js +++ b/js/angular-crmMailing/directives.js @@ -229,14 +229,14 @@ angular.module('crmMailing').directive('crmMailingRecipients', function () { return { restrict: 'AE', + require: 'ngModel', scope: { crmAvailGroups: '@', // available groups crmAvailMailings: '@', // available mailings - crmMailing: '@' // the mailing for which we are choosing recipients }, templateUrl: '~/crmMailing/directive/recipients.html', - link: function (scope, element, attrs) { - scope.mailing = scope.$parent.$eval(attrs.crmMailing); + link: function (scope, element, attrs, ngModel) { + scope.recips = ngModel.$viewValue; scope.groups = scope.$parent.$eval(attrs.crmAvailGroups); scope.mailings = scope.$parent.$eval(attrs.crmAvailMailings); @@ -268,29 +268,29 @@ // @param Object mailing // @return array list of values like "4 civicrm_mailing include" - function convertMailingToValues(mailing) { + function convertMailingToValues(recipients) { var r = []; - angular.forEach(mailing.groups.include, function (v) { + angular.forEach(recipients.groups.include, function (v) { r.push(v + " civicrm_group include"); }); - angular.forEach(mailing.groups.exclude, function (v) { + angular.forEach(recipients.groups.exclude, function (v) { r.push(v + " civicrm_group exclude"); }); - angular.forEach(mailing.mailings.include, function (v) { + angular.forEach(recipients.mailings.include, function (v) { r.push(v + " civicrm_mailing include"); }); - angular.forEach(mailing.mailings.exclude, function (v) { + angular.forEach(recipients.mailings.exclude, function (v) { r.push(v + " civicrm_mailing exclude"); }); return r; } - // Update $(element) view based on latest data - function refreshUI() { - if (scope.mailing) { - $(element).select2('val', convertMailingToValues(scope.mailing)); + var refreshUI = ngModel.$render = function refresuhUI() { + scope.recips = ngModel.$viewValue; + if (ngModel.$viewValue) { + $(element).select2('val', convertMailingToValues(ngModel.$viewValue)); } - } + }; /// @return string HTML representingn an option function formatItem(item) { @@ -318,12 +318,12 @@ var option = convertValueToObj(e.val); var typeKey = option.entity_type == 'civicrm_mailing' ? 'mailings' : 'groups'; if (option.mode == 'exclude') { - scope.mailing[typeKey].exclude.push(option.entity_id); - arrayRemove(scope.mailing[typeKey].include, option.entity_id); + ngModel.$viewValue[typeKey].exclude.push(option.entity_id); + arrayRemove(ngModel.$viewValue[typeKey].include, option.entity_id); } else { - scope.mailing[typeKey].include.push(option.entity_id); - arrayRemove(scope.mailing[typeKey].exclude, option.entity_id); + ngModel.$viewValue[typeKey].include.push(option.entity_id); + arrayRemove(ngModel.$viewValue[typeKey].exclude, option.entity_id); } scope.$apply(); $(element).select2('close'); @@ -334,20 +334,17 @@ var option = convertValueToObj(e.val); var typeKey = option.entity_type == 'civicrm_mailing' ? 'mailings' : 'groups'; scope.$parent.$apply(function () { - arrayRemove(scope.mailing[typeKey][option.mode], option.entity_id); + arrayRemove(ngModel.$viewValue[typeKey][option.mode], option.entity_id); }); e.preventDefault(); }); - scope.$watchCollection(attrs.crmMailing + ".groups.include", refreshUI); - scope.$watchCollection(attrs.crmMailing + ".groups.exclude", refreshUI); - scope.$watchCollection(attrs.crmMailing + ".mailings.include", refreshUI); - scope.$watchCollection(attrs.crmMailing + ".mailings.exclude", refreshUI); + scope.$watchCollection("recips.groups.include", refreshUI); + scope.$watchCollection("recips.groups.exclude", refreshUI); + scope.$watchCollection("recips.mailings.include", refreshUI); + scope.$watchCollection("recips.mailings.exclude", refreshUI); setTimeout(refreshUI, 50); - scope.$watch(attrs.crmMailing, function(){ - scope.mailing = scope.$parent.$eval(attrs.crmMailing); - }); scope.$watchCollection(attrs.crmAvailGroups, function(){ scope.groups = scope.$parent.$eval(attrs.crmAvailGroups); }); diff --git a/js/angular-crmMailing/services.js b/js/angular-crmMailing/services.js index 65861b2c8a..01b04d3287 100644 --- a/js/angular-crmMailing/services.js +++ b/js/angular-crmMailing/services.js @@ -132,12 +132,13 @@ _loadGroups: function (mailing) { return crmApi('MailingGroup', 'get', {mailing_id: mailing.id}) .then(function (groupResult) { - mailing.groups = {include: [], exclude: []}; - mailing.mailings = {include: [], exclude: []}; + mailing.recipients = {}; + mailing.recipients.groups = {include: [], exclude: []}; + mailing.recipients.mailings = {include: [], exclude: []}; _.each(groupResult.values, function (mailingGroup) { var bucket = (/^civicrm_group/.test(mailingGroup.entity_table)) ? 'groups' : 'mailings'; var entityId = parseInt(mailingGroup.entity_id); - mailing[bucket][mailingGroup.group_type.toLowerCase()].push(entityId); + mailing.recipients[bucket][mailingGroup.group_type.toLowerCase()].push(entityId); }); }); }, @@ -153,8 +154,10 @@ create: function create(params) { var defaults = { jobs: {}, // {jobId: JobRecord} - groups: {include: [], exclude: []}, - mailings: {include: [], exclude: []}, + recipients: { + groups: {include: [], exclude: []}, + mailings: {include: [], exclude: []}, + }, name: "", campaign_id: null, replyto_email: "", @@ -190,8 +193,7 @@ 'replyto_email', 'subject', 'dedupe_email', - 'groups', - 'mailings', + 'recipients', 'body_html', 'body_text', 'footer_id', @@ -221,12 +223,13 @@ // @param mailing Object (per APIv3) // @return Promise an object with "subject", "body_text", "body_html" preview: function preview(mailing) { - var params = angular.extend({}, mailing, { + var params = angular.extend({}, mailing, mailing.recipients, { options: {force_rollback: 1}, 'api.Mailing.preview': { id: '$value.id' } }); + delete params.recipients; // the content was merged in return crmApi('Mailing', 'create', params).then(function (result) { // changes rolled back, so we don't care about updating mailing return result.values[result.id]['api.Mailing.preview'].values; @@ -239,7 +242,7 @@ previewRecipients: function previewRecipients(mailing, previewLimit) { // To get list of recipients, we tentatively save the mailing and // get the resulting recipients -- then rollback any changes. - var params = angular.extend({}, mailing, { + var params = angular.extend({}, mailing, mailing.recipients, { name: 'placeholder', // for previewing recipients on new, incomplete mailing subject: 'placeholder', // for previewing recipients on new, incomplete mailing options: {force_rollback: 1}, @@ -251,6 +254,7 @@ 'api.email.getvalue': {'return': 'email'} } }); + delete params.recipients; // the content was merged in return crmApi('Mailing', 'create', params).then(function (recipResult) { // changes rolled back, so we don't care about updating mailing return recipResult.values[recipResult.id]['api.MailingRecipients.get'].values; @@ -261,7 +265,7 @@ // @param mailing Object (per APIv3) // @return Promise save: function(mailing) { - var params = angular.extend({}, mailing); + var params = angular.extend({}, mailing, mailing.recipients); // Angular ngModel sometimes treats blank fields as undefined. angular.forEach(mailing, function(value, key) { @@ -277,6 +281,8 @@ delete params.jobs; + delete params.recipients; // the content was merged in + return crmApi('Mailing', 'create', params).then(function(result) { if (result.id && !mailing.id) { mailing.id = result.id; @@ -311,7 +317,7 @@ // @param to Object with either key "email" (string) or "gid" (int) // @return Promise for a list of delivery reports sendTest: function (mailing, recipient) { - var params = angular.extend({}, mailing, { + var params = angular.extend({}, mailing, mailing.recipients, { // options: {force_rollback: 1}, // Test mailings include tracking features, so the mailing must be persistent 'api.Mailing.send_test': { mailing_id: '$value.id', @@ -327,6 +333,8 @@ delete params.jobs; + delete params.recipients; // the content was merged in + return crmApi('Mailing', 'create', params).then(function (result) { if (result.id && !mailing.id) { mailing.id = result.id; diff --git a/js/angular-crmMailingAB.js b/js/angular-crmMailingAB.js index 279fb12100..657c8c2362 100644 --- a/js/angular-crmMailingAB.js +++ b/js/angular-crmMailingAB.js @@ -86,16 +86,14 @@ case 'Subject lines': crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [ 'name', - 'groups', - 'mailings', + 'recipients', 'subject' ]); break; case 'From names': crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [ 'name', - 'groups', - 'mailings', + 'recipients', 'from_name', 'from_email' ]); @@ -103,8 +101,7 @@ case 'Two different emails': crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [ 'name', - 'groups', - 'mailings', + 'recipients', 'subject', 'from_name', 'from_email', @@ -241,8 +238,7 @@ buttons[ts('Select Winner')] = function () { crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings[mailingName], [ 'name', - 'groups', - 'mailings', + 'recipients', 'scheduled_date' ]); crmStatus({start: ts('Saving...'), success: ''}, abtest.save()) diff --git a/partials/crmMailing/recipients.html b/partials/crmMailing/recipients.html index f285552837..3306ef4aea 100644 --- a/partials/crmMailing/recipients.html +++ b/partials/crmMailing/recipients.html @@ -17,7 +17,7 @@