CRM-15578 - crmMailing2 - Add dedupe and recipients widgets. Refresh recipients autom...
authorTim Otten <totten@civicrm.org>
Wed, 5 Nov 2014 02:57:40 +0000 (18:57 -0800)
committerTim Otten <totten@civicrm.org>
Tue, 11 Nov 2014 00:21:19 +0000 (16:21 -0800)
js/angular-crmMailing2.js
partials/crmMailing2/dialog/recipients.html [new file with mode: 0644]
partials/crmMailing2/field/recipients.html

index 04b9ae1e16d20f207f24ac40e4043d81f68319f9..99d5d6dda211f438ef5400e0efb67a0d244e8586 100644 (file)
@@ -5,6 +5,9 @@
 
   var crmMailing2 = angular.module('crmMailing2', ['ngRoute', 'ui.utils', 'crmUi', 'dialogService']); // TODO ngSanitize, unsavedChanges
 
+  // Time to wait before triggering AJAX update to recipients list
+  var RECIPIENTS_DEBOUNCE_MS = 100;
+
   /**
    * Initialize a new mailing
    * TODO Move to separate file or service
@@ -24,7 +27,8 @@
       from: _.where(CRM.crmMailing.fromAddress, {is_default: "1"})[0].label,
       replyto_email: "",
       subject: "",
-      groups: {include: [], exclude: [4]}, // fixme
+      dedupe_email: "1",
+      groups: {include: [2], exclude: [4]}, // fixme
       mailings: {include: [], exclude: []},
       body_html: "",
       body_text: "",
     };
   });
 
+  // Controller for the edit-recipients fields (
+  // WISHLIST: Move most of this to a (cache-enabled) service
+  // Scope members:
+  //  - [input] mailing: object
+  //  - [output] recipients: array of recipient records
+  crmMailing2.controller('EditRecipCtrl', function ($scope, dialogService, crmApi) {
+    // TODO load & live update real recipients list
+    $scope.recipients = null;
+    $scope.getRecipientsEstimate = function () {
+      var ts = $scope.ts;
+      if ($scope.recipients == null)
+        return ts('(Estimating)');
+      if ($scope.recipients.length == 0)
+        return ts('No recipients');
+      if ($scope.recipients.length == 1)
+        return ts('~1 recipient');
+      return ts('~%1 recipients', {1: $scope.recipients.length});
+    };
+    // We monitor four fields -- use debounce so that changes across the
+    // four fields can settle-down before AJAX.
+    var refreshRecipients = _.debounce(function () {
+      $scope.$apply(function () {
+        $scope.recipients = null;
+        crmApi('Mailing', 'preview_recipients', $scope.mailing)
+                .then(function (recipResult) {
+                  $scope.$apply(function () {
+                    $scope.recipients = recipResult.values;
+                  });
+                });
+      });
+    }, 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.previewRecipients = function () {
+      var model = {
+        recipients: $scope.recipients
+      };
+      var options = {
+        autoOpen: false,
+        modal: true,
+        title: ts('Preview (%1)', {
+          1: $scope.getRecipientsEstimate()
+        }),
+      };
+      dialogService.open('recipDialog', partialUrl('dialog/recipients.html'), model, options)
+        .then(
+          function (result) {
+            // console.log('Closed!');
+          },
+          function (error) {
+            // console.log('Cancelled!');
+          }
+        );
+    };
+  });
+
+  // Controller for the "Preview Recipients" dialog
+  // Note: Expects $scope.model to be an object with properties:
+  //   - recipients: array of contacts
+  crmMailing2.controller('PreviewRecipCtrl', function ($scope) {
+    $scope.ts = CRM.ts('CiviMail');
+  });
 })(angular, CRM.$, CRM._);
diff --git a/partials/crmMailing2/dialog/recipients.html b/partials/crmMailing2/dialog/recipients.html
new file mode 100644 (file)
index 0000000..0e56ada
--- /dev/null
@@ -0,0 +1,24 @@
+<div ng-controller="PreviewRecipCtrl">
+  <!--
+  Controller: PreviewRecipCtrl
+  Required vars: model.recipients
+  -->
+  <p><em>{{ts('Based on current data, the following contacts will receive a copy of the mailing. If contacts are added or removed from the target groups, then the final list may change.')}}</em></p>
+  <div ng-show="model.recipients == 0">
+    {{ts('No recipients')}}
+  </div>
+  <table ng-show="model.recipients.length > 0">
+    <thead>
+      <tr>
+        <th>{{ts('Name')}}</th>
+        <th>{{ts('Email')}}</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr ng-repeat="recipient in model.recipients">
+        <td>{{recipient['api.contact.getvalue']}}</td>
+        <td>{{recipient['api.email.getvalue']}}</td>
+      </tr>
+    </tbody>
+  </table>
+</div>
index 78374240c0281b8315365d18c0ebb126ee28a530..3c3da6d1615de369d6aadde0786e138ab37bcc23 100644 (file)
@@ -2,11 +2,25 @@
 Controller: EditMailingCtrl
 Required vars: mailing, crmMailingConst
 -->
-<select crm-mailing-recipients
-        crm-mailing="mailing"
-        crm-avail-groups="crmMailingConst.groupNames | filter:{visibility:'Public pages'}"
-        crm-avail-mailings="crmMailingConst.civiMails | filter:{is_completed:1}"
-        name="recipients"
-        required
-        multiple>
-</select>
+<div ng-controller="EditRecipCtrl">
+  <div style="float: right;">
+    <div class='crmMailing2-recip-est'>
+      <a href="" ng-click="previewRecipients()">{{getRecipientsEstimate()}}</a>
+    </div>
+    <div>
+      <input name='dedupe_email' type='checkbox' ng-model='mailing.dedupe_email'  ng-true-value="1" ng-false-value="0" />
+      <label crm-ui-label crm-for='dedupe_email'>
+        Dedupe
+      </label>
+    </div>
+  </div>
+
+  <select crm-mailing-recipients
+          crm-mailing="mailing"
+          crm-avail-groups="crmMailingConst.groupNames | filter:{visibility:'Public pages'}"
+          crm-avail-mailings="crmMailingConst.civiMails | filter:{is_completed:1}"
+          name="recipients"
+          required
+          multiple>
+  </select>
+</div>
\ No newline at end of file