APIv4 Explorer - Make WHERE clause code more generic, toward supporting HAVING
authorColeman Watts <coleman@civicrm.org>
Wed, 8 Apr 2020 16:08:40 +0000 (12:08 -0400)
committerColeman Watts <coleman@civicrm.org>
Thu, 9 Apr 2020 16:09:37 +0000 (12:09 -0400)
ang/api4Explorer/Clause.html [moved from ang/api4Explorer/WhereClause.html with 79% similarity]
ang/api4Explorer/Explorer.html
ang/api4Explorer/Explorer.js
css/api4-explorer.css

similarity index 79%
rename from ang/api4Explorer/WhereClause.html
rename to ang/api4Explorer/Clause.html
index 52a237b5047e09778b5fa76a9ef5d2819585ffe0..3fc5cababdfb92612a0845bfa0a9944440d224e0 100644 (file)
@@ -4,11 +4,11 @@
     <i class="crm-i fa-trash"></i>
   </button>
 </div>
-<div class="api4-where-group-sortable" ng-model="data.where" ui-sortable="{axis: 'y', connectWith: '.api4-where-group-sortable', containment: '.api4-where-fieldset', over: onSortOver, start: onSort, stop: onSort}">
-  <div class="api4-input form-inline clearfix" ng-repeat="(index, clause) in data.where">
+<div class="api4-clause-group-sortable" ng-model="data.clauses" ui-sortable="{axis: 'y', connectWith: '.api4-clause-group-sortable', containment: '.api4-clause-fieldset', over: onSortOver}" ui-sortable-start="onSort" ui-sortable-stop="onSort">
+  <div class="api4-input form-inline clearfix" ng-repeat="(index, clause) in data.clauses">
     <div class="api4-clause-badge" title="{{ ts('Drag to reposition') }}">
       <span class="badge badge-info">
-        <span ng-if="!index && !data.groupParent">Where</span>
+        <span ng-if="!index && !data.groupParent">{{ data.type }}</span>
         <span ng-if="index || data.groupParent">{{ data.op }}</span>
         <i class="crm-i fa-arrows"></i>
       </span>
@@ -18,7 +18,7 @@
       <select class="form-control api4-operator" ng-model="clause[1]" ng-options="o for o in operators" ></select>
       <input class="form-control" ng-model="clause[2]" api4-exp-value="{field: clause[0], op: clause[1]}" />
     </div>
-    <fieldset class="clearfix" ng-if="clause[0] === 'AND' || clause[0] === 'OR' || clause[0] === 'NOT'" crm-api4-where-clause="{where: clause[1], op: clause[0], fields: data.fields, operators: data.operators, groupParent: data.where, groupIndex: index}">
+    <fieldset class="clearfix" ng-if="clause[0] === 'AND' || clause[0] === 'OR' || clause[0] === 'NOT'" crm-api4-clause="{type: data.type, clauses: clause[1], op: clause[0], fields: data.fields, groupParent: data.clauses, groupIndex: index}">
     </fieldset>
   </div>
 </div>
index e34476a41672b667a282ed0ec5cb813a0acb157b..ac62ad068e039b60c70d2ad11d764159a3eeb134 100644 (file)
@@ -73,7 +73,7 @@
             <textarea class="form-control" type="{{ param.type[0] === 'int' && param.type.length === 1 ? 'number' : 'text' }}" id="api4-param-{{ name }}" ng-model="params[name]">
             </textarea>
           </div>
-          <fieldset ng-if="availableParams.where" class="api4-where-fieldset" ng-mouseenter="help('where', availableParams.where)" ng-mouseleave="help()" crm-api4-where-clause="{where: params.where, required: availableParams.where.required, op: 'AND', label: 'where', fields: fieldsAndJoins}">
+          <fieldset ng-if="availableParams.where" class="api4-clause-fieldset" ng-mouseenter="help('where', availableParams.where)" ng-mouseleave="help()" crm-api4-clause="{type: 'where', clauses: params.where, required: availableParams.where.required, op: 'AND', label: 'where', fields: fieldsAndJoins}">
           </fieldset>
           <fieldset ng-repeat="name in ['values', 'defaults']" ng-if="availableParams[name]" ng-mouseenter="help(name, availableParams[name])" ng-mouseleave="help()">
             <legend>{{ name }}<span class="crm-marker" ng-if="availableParams[name].required"> *</span></legend>
index a8f825af17c6db4df0c98a0f5ffc85dae1f06f9d..57cc5d60f02b192237f1ee073c449602c7c0fee4 100644 (file)
     };
   });
 
-  angular.module('api4Explorer').directive('crmApi4WhereClause', function($timeout) {
+  angular.module('api4Explorer').directive('crmApi4Clause', function($timeout) {
     return {
       scope: {
-        data: '=crmApi4WhereClause'
+        data: '=crmApi4Clause'
       },
-      templateUrl: '~/api4Explorer/WhereClause.html',
+      templateUrl: '~/api4Explorer/Clause.html',
       link: function (scope, element, attrs) {
         var ts = scope.ts = CRM.ts();
         scope.newClause = '';
         scope.operators = CRM.vars.api4.operators;
 
         scope.addGroup = function(op) {
-          scope.data.where.push([op, []]);
+          scope.data.clauses.push([op, []]);
         };
 
         scope.removeGroup = function() {
         };
 
         scope.onSort = function(event, ui) {
-          $('.api4-where-fieldset').toggleClass('api4-sorting', event.type === 'sortstart');
+          $(element).closest('.api4-clause-fieldset').toggleClass('api4-sorting', event.type === 'sortstart');
           $('.api4-input.form-inline').css('margin-left', '');
         };
 
           var field = value;
           $timeout(function() {
             if (field) {
-              scope.data.where.push([field, '=', '']);
+              scope.data.clauses.push([field, '=', '']);
               scope.newClause = null;
             }
           });
         });
-        scope.$watch('data.where', function(values) {
+        scope.$watch('data.clauses', function(values) {
           // Remove empty values
           _.each(values, function(clause, index) {
             if (typeof clause !== 'undefined' && !clause[0]) {
index 077f95b7bef4a907beaa1eb9d1779de19b56de09..bd309c33b7318ae3f80bd3539e8ab02c08358183 100644 (file)
   top: -2px;
 }
 
-#bootstrap-theme.api4-explorer-page .api4-where-fieldset fieldset {
+#bootstrap-theme.api4-explorer-page .api4-clause-fieldset fieldset {
   float: right;
   width: calc(100% - 58px);
   margin-top: -8px;
 }
 
-#bootstrap-theme.api4-explorer-page .api4-where-fieldset.api4-sorting fieldset .api4-where-group-sortable {
+#bootstrap-theme.api4-explorer-page .api4-clause-fieldset.api4-sorting fieldset .api4-clause-group-sortable {
   min-height: 3.5em;
 }