crmMailingAB - Report - Add options to view mailing content, select winner, & view...
authorTim Otten <totten@civicrm.org>
Sat, 20 Dec 2014 12:50:29 +0000 (04:50 -0800)
committerTim Otten <totten@civicrm.org>
Sat, 20 Dec 2014 13:11:50 +0000 (05:11 -0800)
js/angular-crmMailingAB.js
js/angular-crmMailingAB/services.js
partials/crmMailingAB/report.html
partials/crmMailingAB/selectWinner.html [new file with mode: 0644]

index 6dc3d12cd215c60fd5fdddeb953dd3b0ab834e2a..6dab3a7d8b0fe2a562054591bd20dd9a538004f8 100644 (file)
       $scope.sync();
       return crmStatus({start: ts('Saving...'), success: ''}, abtest.save())
         .then(function () {
-          return crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, abtest.submit('Testing'));
+          return crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, abtest.submitTest());
           // Note: We're going to leave, so we don't care that submit() modifies several server-side records.
-          // If we stayed on this page, then we'd care about updating and call: abtest.submit().then(abtest.load)
+          // If we stayed on this page, then we'd care about updating and call: abtest.submitTest().then(...abtest.load()...)
         })
         .then(leave);
     };
     $scope.$watch('abtest.ab.testing_criteria_id', updateCriteriaName);
   });
 
-  angular.module('crmMailingAB').controller('CrmMailingABReportCtrl', function ($scope, abtest, crmMailingABCriteria, crmApi) {
+  angular.module('crmMailingAB').controller('CrmMailingABReportCtrl', function ($scope, abtest, crmApi, crmMailingPreviewMgr, dialogService) {
     var ts = $scope.ts = CRM.ts('CiviMail');
 
     $scope.abtest = abtest;
     crmApi('Mailing', 'stats', {mailing_id: abtest.ab.mailing_id_b}).then(function(data){
       $scope.stats.b = data.values[abtest.ab.mailing_id_b];
     });
+    crmApi('Mailing', 'stats', {mailing_id: abtest.ab.mailing_id_c}).then(function(data){
+      $scope.stats.c = data.values[abtest.ab.mailing_id_c];
+    });
+
+    $scope.previewMailing = function previewMailing(mailingName, mode) {
+      return crmMailingPreviewMgr.preview(abtest.mailings[mailingName], mode);
+    };
+    $scope.selectWinner = function selectWinner(mailingName) {
+      var model = {
+        abtest: abtest,
+        mailingName: mailingName
+      };
+      var options = {
+        autoOpen: false,
+        modal: true,
+        title: ts('Select Winner (%1)', {
+          1: mailingName.toUpperCase()
+        })
+      };
+      return dialogService.open('selectWinnerDialog', partialUrl('selectWinner.html'), model, options);
+    };
+  });
+
+
+  angular.module('crmMailingAB').controller('CrmMailingABWinnerDialogCtrl', function ($scope, $timeout, dialogService, crmMailingMgr, crmStatus) {
+    var ts = $scope.ts = CRM.ts('CiviMail');
+    var abtest = $scope.abtest = $scope.model.abtest;
+    var mailingName = $scope.model.mailingName;
+
+    var titles = {a: ts('Mailing A'), b: ts('Mailing B')};
+    $scope.mailingTitle = titles[mailingName];
+
+    function init() {
+      // When using dialogService with a button bar, the major button actions
+      // need to be registered with the dialog widget (and not embedded in
+      // the body of the dialog).
+      var buttons = {};
+      buttons[ts('Select Winner')] = function () {
+        crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings[mailingName], [
+          'name',
+          'groups',
+          'mailings',
+          'scheduled_date'
+        ]);
+        crmStatus({start: ts('Saving...'), success: ''}, abtest.save())
+          .then(function () {
+            return crmStatus({start: ts('Submitting...'), success: ts('Submitted')},
+              abtest.submitFinal().then(function(){
+                return abtest.load();
+              }));
+          })
+          .then(function(){
+            dialogService.close('selectWinnerDialog', abtest);
+          });
+      };
+      buttons[ts('Cancel')] = function () {
+        dialogService.cancel('selectWinnerDialog');
+      };
+      dialogService.setButtons('selectWinnerDialog', buttons);
+    }
+
+    $timeout(init);
   });
 
 })(angular, CRM.$, CRM._);
index c602fda731369d216869782417ac11fe3dd5774e..e28eac1fd8e73caa2439dc641472200c52fe4b4d 100644 (file)
           .then(function () {
             return crmApi('MailingAB', 'create', crmMailingAB.ab)
               .then(function (abResult) {
-                crmMailingAB.ab.id = abResult.id;
+                crmMailingAB.id = crmMailingAB.ab.id = abResult.id;
               });
           })
           .then(function () {
       },
       // Schedule the test
       // @return Promise CrmMailingAB
-      // Note: Submission may cause the server state to change. Consider abtest.submit().then(abtest.load)
-      submit: function submit(newStatus) {
+      // Note: Submission may cause the server state to change. Consider abtest.submit().then(...abtest.load()...)
+      submitTest: function submitTest() {
         var crmMailingAB = this;
         var params = {
           id: this.ab.id,
-          status: newStatus,
+          status: 'Testing',
           approval_date: crmNow(),
           scheduled_date: this.mailings.a.scheduled_date ? this.mailings.a.scheduled_date : crmNow()
         };
             return crmMailingAB;
           });
       },
+      // Schedule the final mailing
+      // @return Promise CrmMailingAB
+      // Note: Submission may cause the server state to change. Consider abtest.submit().then(...abtest.load()...)
+      submitFinal: function submitFinal() {
+        var crmMailingAB = this;
+        var params = {
+          id: this.ab.id,
+          status: 'Final',
+          approval_date: crmNow(),
+          scheduled_date: this.mailings.c.scheduled_date ? this.mailings.c.scheduled_date : crmNow()
+        };
+        return crmApi('MailingAB', 'submit', params)
+          .then(function () {
+            return crmMailingAB;
+          });
+      },
       // @param mailing Object (per APIv3)
       // @return Promise
       'delete': function () {
index 00781196533f142cf5f0fd416197a79fba50f401..b9d8ecb643e5d53f3284e049395e275919189a63 100644 (file)
@@ -1,38 +1,70 @@
-<div>
+<div crm-ui-accordion crm-title="ts('Debug')" crm-collapsed="true">
+  <pre>{{abtest.ab|json}}</pre>
+  <pre>{{abtest.mailings|json}}</pre>
+</div>
 
+<div>
   <table>
     <thead>
     <tr>
       <th>{{ts('Details')}}</th>
-      <th style="width: 10em;">{{ts('Mailing A')}}</th>
-      <th style="width: 10em;">{{ts('Mailing B')}}</th>
+      <th style="width: 12em;">{{ts('Mailing A')}}</th>
+      <th style="width: 12em;">{{ts('Mailing B')}}</th>
+      <th style="width: 12em;" ng-show="abtest.ab.status == 'Final'">{{ts('Final')}}</th>
     </tr>
     </thead>
     <tbody>
+    <tr ng-show="abtest.mailings.a.body_html || abtest.mailings.b.body_html">
+      <td>{{ts('HTML')}}</td>
+      <td><a ng-click="previewMailing('a','html')" ng-show="abtest.mailings.a.body_html">{{ts('View')}}</a></td>
+      <td><a ng-click="previewMailing('b','html')" ng-show="abtest.mailings.b.body_html">{{ts('View')}}</a></td>
+      <td><a ng-click="previewMailing('c','html')" ng-show="abtest.mailings.c.body_html && abtest.ab.status == 'Final'">{{ts('View')}}</a></td>
+    </tr>
+    <tr ng-show="abtest.mailings.a.body_text || abtest.mailings.b.body_text">
+      <td>{{ts('Text')}}</td>
+      <td><a ng-click="previewMailing('a','text')" ng-show="abtest.mailings.a.body_text">{{ts('View')}}</a></td>
+      <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('Delivered')}}</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('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('Unsubscribers')}}</td>
       <td>{{stats.a.Unsubscribers}}</td>
       <td>{{stats.b.Unsubscribers}}</td>
+      <td ng-show="abtest.ab.status == 'Final'">{{stats.c.Unsubscribers}}</td>
     </tr>
     <tr>
       <td>{{'Opened'}}</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 ng-show="abtest.ab.status == 'Testing'">
+      <td></td>
+      <td>
+        <button ng-click="selectWinner('a')">{{ts('Select as Winner')}}</button>
+      </td>
+      <td>
+        <button ng-click="selectWinner('b')">{{ts('Select as Winner')}}</button>
+      </td>
+      <!-- Final column is n/a -->
     </tr>
     </tbody>
   </table>
diff --git a/partials/crmMailingAB/selectWinner.html b/partials/crmMailingAB/selectWinner.html
new file mode 100644 (file)
index 0000000..6260224
--- /dev/null
@@ -0,0 +1,19 @@
+<div ng-controller="CrmMailingABWinnerDialogCtrl">
+  <form novalidate name="winnerForm">
+    <div id="help">
+      {{ts('After selecting %1 as the winner, one must schedule the delivery for the final mailing.', {1: mailingTitle})}}
+    </div>
+
+    <div crm-mailing-radio-date="schedule" crm-model="abtest.mailings.c.scheduled_date">
+      <div>
+        <input ng-model="schedule.mode" type="radio" name="send" value="now" id="schedule-send-now"/>
+        <label for="schedule-send-now">{{ts('Send final mailing immediately')}}</label>
+      </div>
+      <div>
+        <input ng-model="schedule.mode" type="radio" name="send" value="at" id="schedule-send-at"/>
+        <label for="schedule-send-at">{{ts('Send final mailing at:')}}</label>
+        <span crm-ui-date-time="schedule.datetime"></span>
+      </div>
+    </div>
+  </form>
+</div>