Merge in 5.25
authorSeamus Lee <seamuslee001@gmail.com>
Mon, 20 Apr 2020 09:16:14 +0000 (19:16 +1000)
committerSeamus Lee <seamuslee001@gmail.com>
Mon, 20 Apr 2020 09:16:14 +0000 (19:16 +1000)
1  2 
Civi/Api4/Generic/DAOGetAction.php
Civi/Api4/Query/Api4SelectQuery.php
ang/api4Explorer/Explorer.html
ang/api4Explorer/Explorer.js

Simple merge
Simple merge
index af771f914532983e29f8e23fcc8a30fbcb42a330,659917ecb2fe8a459cc27c658148f563459784ef..b6c768088a79c7700a2ba100d0ecbbaf63392dbd
                <input class="collapsible-optgroups form-control" ng-model="controls[name]" crm-ui-select="{formatResult: formatSelect2Item, formatSelection: formatSelect2Item, data: fieldList(name), placeholder: ts('Add %1', {1: name.slice(0, -1)})}"/>
              </div>
            </fieldset>
-           <fieldset ng-if="::availableParams.groupBy" ng-mouseenter="help('groupBy', availableParams.groupBy)" ng-mouseleave="help()">
-             <legend>groupBy<span class="crm-marker" ng-if="::availableParams.groupBy.required"> *</span></legend>
-             <div ng-model="params.groupBy" ui-sortable="{axis: 'y'}">
-               <div class="api4-input form-inline" ng-repeat="item in params.groupBy track by $index">
-                 <i class="crm-i fa-arrows"></i>
-                 <input class="form-control huge" type="text" ng-model="params.groupBy[$index]" />
-                 <a href class="crm-hover-button" title="Clear" ng-click="clearParam('groupBy', $index)"><i class="crm-i fa-times"></i></a>
-               </div>
-             </div>
-             <div class="api4-input form-inline">
-               <input class="collapsible-optgroups form-control huge" ng-model="controls.groupBy" crm-ui-select="{data: fieldsAndJoinsAndFunctions}" placeholder="Add groupBy" />
-             </div>
-           </fieldset>
-           <fieldset ng-if="::availableParams.having" class="api4-clause-fieldset" ng-mouseenter="help('having', availableParams.having)" ng-mouseleave="help()" crm-api4-clause="{type: 'having', clauses: params.having, required: availableParams.having.required, op: 'AND', label: 'having', fields: havingOptions}">
-           </fieldset>
-           <fieldset ng-if="::availableParams.orderBy" ng-mouseenter="help('orderBy', availableParams.orderBy)" ng-mouseleave="help()">
-             <legend>orderBy<span class="crm-marker" ng-if="::availableParams.orderBy.required"> *</span></legend>
-             <div ng-model="params.orderBy" ui-sortable="{axis: 'y'}">
-               <div class="api4-input form-inline" ng-repeat="clause in params.orderBy">
-                 <i class="crm-i fa-arrows"></i>
-                 <input class="form-control huge" type="text" ng-model="clause[0]" />
-                 <select class="form-control" ng-model="clause[1]">
-                   <option value="ASC">ASC</option>
-                   <option value="DESC">DESC</option>
-                 </select>
-                 <a href class="crm-hover-button" title="Clear" ng-click="clearParam('orderBy', $index)"><i class="crm-i fa-times"></i></a>
-               </div>
+           <fieldset ng-if="availableParams.orderBy" ng-mouseenter="help('orderBy', availableParams.orderBy)" ng-mouseleave="help()">
+             <legend>orderBy<span class="crm-marker" ng-if="availableParams.orderBy.required"> *</span></legend>
+             <div class="api4-input form-inline" ng-repeat="clause in params.orderBy">
+               <input class="collapsible-optgroups form-control" ng-model="clause[0]" crm-ui-select="{data: fieldsAndJoins, allowClear: true, placeholder: 'Field'}" />
+               <select class="form-control" ng-model="clause[1]">
+                 <option value="ASC">ASC</option>
+                 <option value="DESC">DESC</option>
+               </select>
              </div>
              <div class="api4-input form-inline">
 -              <input class="collapsible-optgroups form-control" ng-model="controls.orderBy" crm-ui-select="{data: fieldsAndJoins}" placeholder="Add orderBy" />
 +              <input class="collapsible-optgroups form-control huge" ng-model="controls.orderBy" crm-ui-select="{data: fieldsAndJoinsAndFunctions}" placeholder="Add orderBy" />
              </div>
            </fieldset>
-           <fieldset ng-if="::availableParams.limit && availableParams.offset">
-             <div class="api4-input form-inline">
-               <span ng-mouseenter="help('limit', availableParams.limit)" ng-mouseleave="help()">
-                 <label for="api4-param-limit">limit<span class="crm-marker" ng-if="::availableParams.limit.required"> *</span></label>
-                 <input class="form-control" type="number" min="0" id="api4-param-limit" ng-model="params.limit"/>
-               </span>
-               <span ng-mouseenter="help('offset', availableParams.offset)" ng-mouseleave="help()">
-                 <label for="api4-param-offset">offset<span class="crm-marker" ng-if="::availableParams.offset.required"> *</span></label>
-                 <input class="form-control" type="number" min="0" id="api4-param-offset" ng-model="params.offset"/>
-               </span>
-               <a href class="crm-hover-button" title="Clear" ng-click="clearParam('limit');clearParam('offset');" ng-show="!!params.limit || !!params.offset"><i class="crm-i fa-times"></i></a>
-             </div>
-           </fieldset>
-           <fieldset ng-if="::availableParams.chain" ng-mouseenter="help('chain', availableParams.chain)" ng-mouseleave="help()">
+           <fieldset ng-if="availableParams.chain" ng-mouseenter="help('chain', availableParams.chain)" ng-mouseleave="help()">
              <legend>chain</legend>
 -            <div class="api4-input form-inline" ng-repeat="clause in params.chain" api4-exp-chain="clause" entities="entities" main-entity="entity" >
 +            <div class="api4-input form-inline" ng-repeat="clause in params.chain" api4-exp-chain="clause" entities="::entities" main-entity="::entity" >
              </div>
              <div class="api4-input form-inline">
 -              <input class="form-control" ng-model="controls.chain" crm-ui-select="{data: entities}" placeholder="Add chain" />
 +              <input class="form-control" ng-model="controls.chain" crm-ui-select="::{data: entities}" placeholder="Add chain" />
              </div>
            </fieldset>
          </div>
index 369474fc0bf18476dff942a5ebd839017af3e4e1,09db7d1d02a2023fee9ea88a87af0f7e462f5bf5..1db4d564f80503629b035488940bb9f78c762360
          (row.description ? '<div class="crm-select2-row-description"><p>' + _.escape(row.description) + '</p></div>' : '');
      };
  
 -    $scope.clearParam = function(name) {
 -      $scope.params[name] = $scope.availableParams[name].default;
 +    $scope.clearParam = function(name, idx) {
 +      if (typeof idx === 'undefined') {
 +        $scope.params[name] = $scope.availableParams[name].default;
 +      } else {
 +        $scope.params[name].splice(idx, 1);
 +      }
      };
  
-     // 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 _.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.isSpecial = function(name) {
+       var specialParams = ['select', 'fields', 'action', 'where', 'values', 'defaults', 'orderBy', 'chain'];
+       return _.contains(specialParams, name);
      };
  
      $scope.selectRowCount = function() {
                deep: format === 'json'
              });
            }
-           if (typeof objectParams[name] !== 'undefined' && name !== 'orderBy') {
-             $scope.$watch('params.' + name, function (values) {
+           if (typeof objectParams[name] !== 'undefined') {
+             $scope.$watch('params.' + name, function(values) {
                // Remove empty values
 -              _.each(values, function(clause, index) {
 +              _.each(values, function (clause, index) {
                  if (!clause || !clause[0]) {
 -                  $scope.params[name].splice(index, 1);
 +                  $scope.clearParam(name, index);
                  }
                });
              }, true);