CRM-15856 - Required tokens - Display rich dialog
authorTim Otten <totten@civicrm.org>
Thu, 12 Feb 2015 19:45:55 +0000 (11:45 -0800)
committerTim Otten <totten@civicrm.org>
Thu, 12 Feb 2015 20:01:50 +0000 (12:01 -0800)
js/angular-crmMailing.js
partials/crmMailing/body_html.html
partials/crmMailing/body_text.html
partials/crmMailing/dialog/tokenAlert.html [new file with mode: 0644]
partials/crmMailing/headerFooter.html

index f75cdf450eb6458eeead51f4c84fb85bf663608f..3077d4d11be0ab08a3ab7b8767a1d87d6042a0f4 100644 (file)
   });
 
   var lastEmailTokenAlert = null;
-  angular.module('crmMailing').controller('EmailBodyCtrl', function EmailBodyCtrl($scope, crmMailingMgr) {
+  angular.module('crmMailing').controller('EmailBodyCtrl', function EmailBodyCtrl($scope, crmMailingMgr, crmUiAlert, $timeout) {
     var ts = CRM.ts(null);
 
-    $scope.hasAllTokens = function hasMissingTokens(mailing, field) {
+    // ex: if (!hasAllTokens(myMailing, 'body_text)) alert('Oh noes!');
+    $scope.hasAllTokens = function hasAllTokens(mailing, field) {
       return _.isEmpty(crmMailingMgr.findMissingTokens(mailing, field));
     };
 
-    $scope.checkTokens = function checkTokens(mailing) {
+    // ex: checkTokens(myMailing, 'body_text', 'insert:body_text')
+    // ex: checkTokens(myMailing, '*')
+    $scope.checkTokens = function checkTokens(mailing, field, insertEvent) {
       if (lastEmailTokenAlert) {
         lastEmailTokenAlert.close();
       }
-      var missing = angular.extend(
-        {},
-        crmMailingMgr.findMissingTokens(mailing, 'body_html'),
-        crmMailingMgr.findMissingTokens(mailing, 'body_text')
-      );
-      if (! _.isEmpty(missing)) {
-        var buf = '<p>' +
-          ts('Before submitting this mailing, you must include an address token and an action token as part of the mailing body, mailing header, or mailing footer.') +
-          '</p><ul>';
-        angular.forEach(missing, function(msg, token) {
-          // FIXME LTR RTL
-          buf = buf + '<li>{' + token + '} - <em>' + msg + '</em></li>';
+      var missing, insertable;
+      if (field == '*') {
+        insertable = false;
+        missing = angular.extend({},
+          crmMailingMgr.findMissingTokens(mailing, 'body_html'),
+          crmMailingMgr.findMissingTokens(mailing, 'body_text')
+        );
+      } else {
+        insertable = !_.isEmpty(insertEvent);
+        missing = crmMailingMgr.findMissingTokens(mailing, field);
+      }
+      if (!_.isEmpty(missing)) {
+        lastEmailTokenAlert = crmUiAlert({
+          type: 'error',
+          title: ts('Required tokens'),
+          templateUrl: '~/crmMailing/dialog/tokenAlert.html',
+          scope: angular.extend($scope.$new(), {
+            insertable: insertable,
+            insertToken: function(token) {
+              $timeout(function(){
+                $scope.$broadcast(insertEvent, '{' + token + '}');
+                $timeout(function(){
+                  checkTokens(mailing, field, insertEvent);
+                });
+              });
+            },
+            missing: missing
+          })
         });
-        buf += '</ul>';
-        lastEmailTokenAlert = CRM.alert(buf, undefined, 'error');
       }
     };
   });
index 9fd7469b77ad8b65cdafe7e962d60f9a1073e926..e1d23a894993e37b8146528e7d89e877ff9b9e50 100644 (file)
@@ -13,7 +13,8 @@ Required vars: mailing
         crm-ui-richtext name="body_html"
         crm-ui-insert-rx="insert:body_html"
         ng-model="mailing.body_html"
-        ng-blur="checkTokens(mailing)"></textarea>
+        ng-blur="checkTokens(mailing, 'body_html', 'insert:body_html')"
+        ></textarea>
       <span ng-model="body_html_tokens" crm-ui-validate="hasAllTokens(mailing, 'body_html')"></span>
     </div>
   </div>
index 1e2ad5cda38fc90e6e7b7f08e3fa723fb9329a31..f3ac7c7598bbc745cb2d7117ec430efb1b8f247b 100644 (file)
@@ -13,7 +13,8 @@ Required vars: mailing, crmMailingConst
         crm-ui-insert-rx="insert:body_text"
         name="body_text"
         ng-model="mailing.body_text"
-        ng-blur="checkTokens(mailing)"></textarea>
+        ng-blur="checkTokens(mailing, 'body_text', 'insert:body_text')"
+        ></textarea>
       <span ng-model="body_text_tokens" crm-ui-validate="hasAllTokens(mailing, 'body_text')"></span>
     </div>
   </div>
diff --git a/partials/crmMailing/dialog/tokenAlert.html b/partials/crmMailing/dialog/tokenAlert.html
new file mode 100644 (file)
index 0000000..dc32303
--- /dev/null
@@ -0,0 +1,82 @@
+<p ng-show="missing['domain.address']">
+  {{ts('The mailing must include the street address of the organization. Please insert the %1 token.', {1:
+  '{domain.address}'})}}
+</p>
+
+<div ng-show="missing['domain.address'] && insertable">
+  <a ng-click="insertToken('domain.address')" class="button"><span><span
+    class='icon ui-icon-circle-plus'></span> {{ts('Address')}}</span></a>
+
+  <div class="clear"/>
+</div>
+
+<p ng-show="missing['action.optOut']">
+  {{ts('The mailing must allow recipients to (a) unsubscribe from the mailing-list or (b) completely opt-out from all
+  mailings. Please insert an unsubscribe or opt-out token.')}}
+</p>
+
+<div ng-show="missing['action.optOut'] && insertable">
+  <table>
+    <thead>
+    <tr>
+      <th>{{ts('Via Web')}}</th>
+      <th>{{ts('Via Email')}}</th>
+    </tr>
+    </thead>
+    <tbody>
+    <tr>
+      <td>
+        <a ng-click="insertToken('action.unsubscribeUrl')" class="button"><span><span
+          class='icon ui-icon-circle-plus'></span> {{ts('Unsubscribe')}}</span></a>
+      </td>
+      <td>
+        <a ng-click="insertToken('action.unsubscribe')" class="button"><span><span
+          class='icon ui-icon-circle-plus'></span> {{ts('Unsubscribe')}}</span></a>
+      </td>
+    </tr>
+    <tr>
+      <td>
+        <a ng-click="insertToken('action.optOutUrl')" class="button"><span><span
+          class='icon ui-icon-circle-plus'></span> {{ts('Opt-out')}}</span></a>
+      </td>
+      <td>
+        <a ng-click="insertToken('action.optOut')" class="button"><span><span
+          class='icon ui-icon-circle-plus'></span> {{ts('Opt-out')}}</span></a>
+      </td>
+    </tr>
+    </tbody>
+  </table>
+</div>
+
+<div ng-show="missing['action.optOut'] && !insertable">
+  <table>
+    <thead>
+    <tr>
+      <th>{{ts('Via Web')}}</th>
+      <th>{{ts('Via Email')}}</th>
+    </tr>
+    </thead>
+    <tbody>
+    <tr>
+      <td>
+        {action.optOutUrl}
+      </td>
+      <td>
+        {action.optOut}
+      </td>
+    </tr>
+    <tr>
+      <td>
+        {action.unsubscribeUrl}
+      </td>
+      <td>
+        {action.unsubscribe}
+      </td>
+    </tr>
+    </tbody>
+  </table>
+</div>
+
+<p>
+  {{ts('Alternatively, you may select a header or footer which includes the required tokens.')}}
+</p>
index 11a2910760cae933d46199f23ad66a65e011c89d..5446b7e7d942103f549e57b9d7091de95603d797 100644 (file)
@@ -10,7 +10,7 @@ Required vars: mailing, crmMailingConst
         name="header_id"
         ui-jq="select2"
         ui-options="{dropdownAutoWidth : true, allowClear: true}"
-        ng-change="checkTokens(mailing)"
+        ng-change="checkTokens(mailing, '*')"
         ng-model="mailing.header_id"
         ng-options="mc.id as mc.name for mc in crmMailingConst.headerfooterList | filter:{component_type: 'Header'}">
         <option value=""></option>
@@ -22,7 +22,7 @@ Required vars: mailing, crmMailingConst
         name="footer_id"
         ui-jq="select2"
         ui-options="{dropdownAutoWidth : true, allowClear: true}"
-        ng-change="checkTokens(mailing)"
+        ng-change="checkTokens(mailing, '*')"
         ng-model="mailing.footer_id"
         ng-options="mc.id as mc.name for mc in crmMailingConst.headerfooterList | filter:{component_type: 'Footer'}">
         <option value=""></option>