crmMailingAB - Hyperlinks for stats. Get stats in a batch.
authorTim Otten <totten@civicrm.org>
Thu, 19 Feb 2015 03:00:49 +0000 (19:00 -0800)
committerTim Otten <totten@civicrm.org>
Thu, 19 Feb 2015 23:04:07 +0000 (15:04 -0800)
js/angular-crmMailing/services.js
js/angular-crmMailingAB.js
partials/crmMailingAB/report.html

index 1ee3c893787f73dbcd02a8a4c6621a55381ea4af..96dc1b6e83290a6a13ea264a51b6a5c3bbfd8918 100644 (file)
     };
   });
 
+  angular.module('crmMailing').factory('crmMailingStats', function (crmApi, crmLegacy) {
+    var statTypes = [
+      // {name: 'Recipients', title: ts('Intended Recipients'),   searchFilter: '',                           eventsFilter: '&event=queue'},
+      {name: 'Delivered',     title: ts('Successful Deliveries'), searchFilter: '&mailing_delivery_status=Y', eventsFilter: '&event=delivered'},
+      {name: 'Opened',        title: ts('Tracked Opens'),         searchFilter: '&mailing_open_status=Y',     eventsFilter: '&event=opened'},
+      {name: 'Unique Clicks', title: ts('Click-throughs'),        searchFilter: '&mailing_click_status=Y',    eventsFilter: '&event=click&distinct=1'},
+      // {name: 'Forward',    title: ts('Forwards'),              searchFilter: '&mailing_forward=1',         eventsFilter: '&event=forward'},
+      // {name: 'Replies',    title: ts('Replies'),               searchFilter: '&mailing_reply_status=Y',    eventsFilter: '&event=reply'},
+      {name: 'Bounces',       title: ts('Bounces'),               searchFilter: '&mailing_delivery_status=N', eventsFilter: '&event=bounce'},
+      {name: 'Unsubscribers', title: ts('Unsubscribes'),          searchFilter: '&mailing_unsubscribe=1',     eventsFilter: '&event=unsubscribe'}
+      // {name: 'OptOuts',    title: ts('Opt-Outs'),              searchFilter: '&mailing_optout=1',          eventsFilter: '&event=optout'}
+    ];
+
+    return {
+      getStatTypes: function() {
+        return statTypes;
+      },
+
+      /**
+       * @param mailingIds object
+       *   List of mailing IDs ({a: 123, b: 456})
+       * @return Promise
+       *   List of stats for each mailing
+       *   ({a: ...object..., b: ...object...})
+       */
+      getStats: function(mailingIds) {
+        var params = {};
+        angular.forEach(mailingIds, function(mailingId, name) {
+          params[name] = ['Mailing', 'stats', {mailing_id: mailingId}];
+        });
+        return crmApi(params).then(function(result) {
+          var stats = {};
+          angular.forEach(mailingIds, function(mailingId, name) {
+            stats[name] = result[name].values[mailingId];
+          });
+          return stats;
+        });
+      },
+
+      /**
+       * Determine the legacy URL for a report about a given mailing and stat.
+       *
+       * @param mailing object
+       * @param statType object (see statTypes above)
+       * @param view string ('search', 'event', 'report')
+       * @return string|null
+       */
+      getUrl: function getUrl(mailing, statType, view) {
+        switch (view) {
+          case 'events':
+            return crmLegacy.url('civicrm/mailing/report/event',
+              'reset=1&mid=' + mailing.id + statType.eventsFilter);
+
+          case 'search':
+            return crmLegacy.url('civicrm/contact/search/advanced',
+              'force=1&mailing_id=' + mailing.id + statType.searchFilter);
+
+          // TODO: case 'report':
+          default:
+            return null;
+        }
+      }
+    };
+  });
+
 })(angular, CRM.$, CRM._);
index 4d30b29de2b5835ef67981cb8ddd5f1aea8f7b2b..89d49bdfe2c08487ed08e4efeb69a08fc3035f4b 100644 (file)
     $scope.$on('$destroy', myAutosave.stop);
   });
 
-  angular.module('crmMailingAB').controller('CrmMailingABReportCtrl', function ($scope, crmApi, crmMailingStats, crmLegacy) {
+  angular.module('crmMailingAB').controller('CrmMailingABReportCtrl', function ($scope, crmApi, crmMailingStats) {
     var ts = $scope.ts = CRM.ts(null);
 
-    $scope.stats = {};
-    crmApi('Mailing', 'stats', {mailing_id: $scope.abtest.ab.mailing_id_a}).then(function(data){
-      $scope.stats.a = data.values[$scope.abtest.ab.mailing_id_a];
-    });
-    crmApi('Mailing', 'stats', {mailing_id: $scope.abtest.ab.mailing_id_b}).then(function(data){
-      $scope.stats.b = data.values[$scope.abtest.ab.mailing_id_b];
-    });
-    crmApi('Mailing', 'stats', {mailing_id: $scope.abtest.ab.mailing_id_c}).then(function(data){
-      $scope.stats.c = data.values[$scope.abtest.ab.mailing_id_c];
+    crmMailingStats.getStats({
+      a: $scope.abtest.ab.mailing_id_a,
+      b: $scope.abtest.ab.mailing_id_b,
+      c: $scope.abtest.ab.mailing_id_c
+    }).then(function(stats) {
+      $scope.stats = stats;
     });
+
+    $scope.statTypes = crmMailingStats.getStatTypes();
+    $scope.statUrl = function statUrl(mailing, statType, view) {
+      return crmMailingStats.getUrl(mailing, statType, view);
+    };
   });
 
   angular.module('crmMailingAB').controller('CrmMailingABWinnerDialogCtrl', function ($scope, $timeout, dialogService, crmMailingMgr, crmStatus) {
index 4913630e07e394608ffad9632c8e5cddc32748a8..89a0d8a38b3ae3eadd3c1963a2607159e188c8f9 100644 (file)
       <td><a ng-click="previewMailing('b','text')" ng-show="abtest.mailings.b.body_text">{{ts('View')}}</a></td>
       <td><a ng-click="previewMailing('c','text')" ng-show="abtest.mailings.c.body_text && abtest.ab.status == 'Final'">{{ts('View')}}</a></td>
     </tr>
-    <tr>
-      <td>{{ts('Deliveries')}}</td>
-      <td>{{stats.a.Delivered}}</td>
-      <td>{{stats.b.Delivered}}</td>
-      <td ng-show="abtest.ab.status == 'Final'">{{stats.c.Delivered}}</td>
-    </tr>
-    <tr>
-      <td>{{ts('Opens')}}</td>
-      <td>{{stats.a.Opened}}</td>
-      <td>{{stats.b.Opened}}</td>
-      <td ng-show="abtest.ab.status == 'Final'">{{stats.c.Opened}}</td>
-    </tr>
-    <tr>
-      <td>{{ts('Unique Clicks')}}</td>
-      <td>{{stats.a['Unique Clicks']}}</td>
-      <td>{{stats.b['Unique Clicks']}}</td>
-      <td ng-show="abtest.ab.status == 'Final'">{{stats.c['Unique Clicks']}}</td>
-    </tr>
-    <tr>
-      <td>{{ts('Bounces')}}</td>
-      <td>{{stats.a.Bounces}}</td>
-      <td>{{stats.b.Bounces}}</td>
-      <td ng-show="abtest.ab.status == 'Final'">{{stats.c.Bounces}}</td>
-    </tr>
-    <tr>
-      <td>{{ts('Unsubscribes')}}</td>
-      <td>{{stats.a.Unsubscribers}}</td>
-      <td>{{stats.b.Unsubscribers}}</td>
-      <td ng-show="abtest.ab.status == 'Final'">{{stats.c.Unsubscribers}}</td>
+    <tr ng-repeat="statType in statTypes">
+      <td>{{statType.title}}</td>
+      <td>
+        <a class="crm-hover-button" ng-href="{{statUrl(abtest.mailings.a, statType, 'events')}}" title="{{statType.title}}">{{stats.a[statType.name] || ts('n/a')}}</a>
+        <a class="crm-hover-button" ng-href="{{statUrl(abtest.mailings.a, statType, 'search')}}" title="{{ts('Search for contacts')}}" crm-icon="search"></a>
+      </td>
+      <td>
+        <a class="crm-hover-button" ng-href="{{statUrl(abtest.mailings.b, statType, 'events')}}" title="{{statType.title}}">{{stats.b[statType.name] || ts('n/a')}}</a>
+        <a class="crm-hover-button" ng-href="{{statUrl(abtest.mailings.b, statType, 'search')}}" title="{{ts('Search for contacts')}}" crm-icon="search"></a>
+      </td>
+      <td ng-show="abtest.ab.status == 'Final'">
+        <a class="crm-hover-button" ng-href="{{statUrl(abtest.mailings.c, statType, 'events')}}" title="{{statType.title}}">{{stats.a[statType.name] || ts('n/a')}}</a>
+        <a class="crm-hover-button" ng-href="{{statUrl(abtest.mailings.c, statType, 'search')}}" title="{{ts('Search for contacts')}}" crm-icon="search"></a>
+      </td>
     </tr>
     <tr ng-show="abtest.ab.status == 'Testing'">
       <td></td>