APIv4 Explorer - performance boost with less intensive loops
authorColeman Watts <coleman@civicrm.org>
Mon, 13 Apr 2020 02:09:16 +0000 (22:09 -0400)
committerColeman Watts <coleman@civicrm.org>
Mon, 13 Apr 2020 15:29:52 +0000 (11:29 -0400)
ang/api4Explorer/Explorer.html
ang/api4Explorer/Explorer.js

index d6e08c74ed33fa4176625681026f410a835fc295..becc31b500c55969ee317e953d39be0326a61ee9 100644 (file)
@@ -31,7 +31,7 @@
         </div>
         <div class="panel-body">
           <div class="api4-input form-inline">
-            <label class="form-control" ng-mouseenter="help(name, param)" ng-mouseleave="help()" ng-class="{'api4-option-selected': params[name]}" ng-repeat="(name, param) in availableParams" ng-if="!isSpecial(name) && param.type[0] === 'bool' && param.default !== null">
+            <label class="form-control" ng-mouseenter="help(name, param)" ng-mouseleave="help()" ng-class="{'api4-option-selected': params[name]}" ng-repeat="(name, param) in ::getGenericParams(['bool'], false)">
               <input type="checkbox" id="api4-param-{{:: name }}" ng-model="params[name]"/>
               {{:: name }}<span class="crm-marker" ng-if="::param.required"> *</span>
             </label>
@@ -40,7 +40,7 @@
               SelectRowCount
             </label>
           </div>
-          <div class="api4-input form-inline" ng-mouseenter="help(name, param)" ng-mouseleave="help()" ng-repeat="(name, param) in availableParams" ng-if="!isSpecial(name) && param.type[0] === 'bool' && param.default === null">
+          <div class="api4-input form-inline" ng-mouseenter="help(name, param)" ng-mouseleave="help()" ng-repeat="(name, param) in ::getGenericParams(['bool'], true)">
             <label>{{ name }}<span class="crm-marker" ng-if="::param.required"> *</span></label>
             <label class="radio-inline">
               <input type="radio" ng-model="params[name]" ng-value="true" />true
             <label for="api4-param-action">action<span class="crm-marker" ng-if="::availableParams.action.required"> *</span></label>
             <input class="form-control" crm-ui-select="{data: actions, allowClear: true, placeholder: 'None'}" id="api4-param-action" ng-model="params.action"/>
           </div>
-          <div class="api4-input form-inline" ng-mouseenter="help(name, param)" ng-mouseleave="help()" ng-repeat="(name, param) in availableParams" ng-if="!isSpecial(name) && (param.type[0] === 'string' || param.type[0] === 'int')">
+          <div class="api4-input form-inline" ng-mouseenter="help(name, param)" ng-mouseleave="help()" ng-repeat="(name, param) in ::getGenericParams(['string', 'int'])">
             <label for="api4-param-{{:: name }}">{{:: name }}<span class="crm-marker" ng-if="::param.required"> *</span></label>
             <input class="form-control" ng-if="::!param.options" type="{{:: param.type[0] === 'int' && param.type.length === 1 ? 'number' : 'text' }}" id="api4-param-{{:: name }}" ng-model="params[name]"/>
             <select class="form-control" ng-if="::param.options" ng-options="o for o in ::param.options" id="api4-param-{{:: name }}" ng-model="params[name]"></select>
             <a href class="crm-hover-button" title="Clear" ng-click="clearParam(name)" ng-show="!!params[name]"><i class="crm-i fa-times"></i></a>
           </div>
-          <div class="api4-input" ng-mouseenter="help(name, param)" ng-mouseleave="help()" ng-repeat="(name, param) in availableParams" ng-if="!isSpecial(name) && (param.type[0] === 'array' || param.type[0] === 'mixed')">
+          <div class="api4-input" ng-mouseenter="help(name, param)" ng-mouseleave="help()" ng-repeat="(name, param) in ::getGenericParams(['array', 'mixed'])">
             <label for="api4-param-{{:: name }}">{{:: name }}<span class="crm-marker" ng-if="::param.required"> *</span></label>
             <textarea class="form-control" type="{{:: param.type[0] === 'int' && param.type.length === 1 ? 'number' : 'text' }}" id="api4-param-{{:: name }}" ng-model="params[name]">
             </textarea>
index a9f0459c48fee4e61506405a7d8b5559c430d640..b1f1ab733ab239881c570b715c4af238264a344e 100644 (file)
       }
     };
 
-    $scope.isSpecial = function(name) {
+    // Gets params that should be represented as generic input fields in the explorer
+    // This fn doesn't have to be particularly efficient as its output is cached in one-time bindings
+    $scope.getGenericParams = function(paramType, defaultNull) {
+      // Returns undefined if params are not yet set; one-time bindings will stabilize when this function returns a value
+      if (_.isEmpty($scope.availableParams)) {
+        return;
+      }
       var specialParams = ['select', 'fields', 'action', 'where', 'values', 'defaults', 'orderBy', 'chain', 'groupBy', 'having'];
       if ($scope.availableParams.limit && $scope.availableParams.offset) {
         specialParams.push('limit', 'offset');
       }
-      return _.contains(specialParams, name);
+      return _.transform($scope.availableParams, function(genericParams, param, name) {
+        if (!_.contains(specialParams, name) &&
+          !(typeof paramType !== 'undefined' && !_.contains(paramType, param.type[0])) &&
+          !(typeof defaultNull !== 'undefined' && ((param.default === null) !== defaultNull))
+        ) {
+          genericParams[name] = param;
+        }
+      });
     };
 
     $scope.selectRowCount = function() {