SearchKit - Support pseudofields and operators in conditional css rules
authorColeman Watts <coleman@civicrm.org>
Tue, 18 Jan 2022 00:25:25 +0000 (19:25 -0500)
committerColeman Watts <coleman@civicrm.org>
Tue, 18 Jan 2022 00:40:21 +0000 (19:40 -0500)
Allows operators other than `=` in conditional style rules.
Also supports pseudofields like `row_number`.

ext/search_kit/Civi/Api4/Action/SearchDisplay/AbstractRunAction.php
ext/search_kit/ang/crmSearchAdmin.module.js
ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminCssRules.component.js
ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminCssRules.html

index f6957086d0790aef50d9d150153a6f75c2ab2b1f..b41452d6e55ae0838f3d17317ef92b6a5a36878e 100644 (file)
@@ -306,10 +306,8 @@ abstract class AbstractRunAction extends \Civi\Api4\Generic\AbstractAction {
    */
   protected function getCssRuleCondition($clause) {
     $fieldKey = $clause[1] ?? NULL;
-    // For fields used in group by, add aggregation and change operator from = to CONTAINS
-    // FIXME: This assumes the operator is always set to '=', which so far is all the admin UI supports.
-    // That's only a safe assumption as long as the admin UI doesn't have an operator selector.
-    // @see ang/crmSearchAdmin/displays/common/searchAdminCssRules.html
+    // For fields used in group by, add aggregation and change operator to CONTAINS
+    // NOTE: This doesn't support any other operators for aggregated fields.
     if ($fieldKey && $this->canAggregate($fieldKey)) {
       $clause[2] = 'CONTAINS';
       $fieldKey = 'GROUP_CONCAT_' . str_replace(['.', ':'], '_', $clause[1]);
index 7edab31d64fa146fb880bcb15f0346053bfd6847..c0e2f53c56d94f0b0a7adf5ef1ef7846e317e731 100644 (file)
         }
         // Might be a pseudoField
         if (!field) {
-          field = _.cloneDeep(_.find(CRM.crmSearchAdmin.pseudoFields, {name: name}));
+          field = _.find(CRM.crmSearchAdmin.pseudoFields, {name: name});
         }
         if (field) {
           field.baseEntity = entityName;
index b19ade12fd409e3ef07e25d57e7f8301203eca7a..40163abb7d8e7a91c3ca4c1ef2d40cef679be662 100644 (file)
       this.styles.strikethrough = ts('Strikethrough');
 
       this.fields = function() {
-        return {results: ctrl.crmSearchAdmin.getAllFields(':name', ['Field', 'Custom', 'Extra'])};
+        var allFields = ctrl.crmSearchAdmin.getAllFields(':name', ['Field', 'Custom', 'Extra', 'Pseudo']);
+        return {
+          results: ctrl.crmSearchAdmin.getSelectFields().concat(allFields)
+        };
       };
 
       this.$onInit = function() {
@@ -61,8 +64,7 @@
         return !this.item.cssRules || !this.item.cssRules.length || _.last(this.item.cssRules)[1];
       };
 
-
-
+      this.operators = CRM.crmSearchAdmin.operators;
     }
   });
 
index cf9e7db74559250c1d926a2896a00c564141d4dc..6b6d573bbe8d4abf368ad82d804d8b3514e2c962 100644 (file)
@@ -22,9 +22,9 @@
   </div>
   <label>{{:: ts('If') }}</label>
   <input class="form-control collapsible-optgroups" ng-model="clause[1]" crm-ui-select="::{data: $ctrl.fields, allowClear: true, placeholder: ts('Always')}" ng-change="$ctrl.onSelectField(clause)" />
-  <!-- TODO: Support operators other than '=' as clause[2] -->
-  <label ng-if="clause[1]">{{:: ts('Is') }}</label>
-  <crm-search-input ng-if="clause[1]" ng-model="clause[3]" field="$ctrl.getField(clause[1])" option-key="'name'" op="clause[1]" format="$ctrl.format" class="form-group"></crm-search-input>
+  <select class="form-control api4-operator" ng-if="clause[1]" ng-model="clause[2]" ng-options="o.key as o.value for o in $ctrl.operators">
+  </select>
+  <crm-search-input ng-if="clause[1] && clause[2].indexOf('IS ') !== 0" ng-model="clause[3]" field="$ctrl.getField(clause[1])" option-key="'name'" op="clause[2]" format="$ctrl.format" class="form-group"></crm-search-input>
   <button type="button" class="btn-xs btn-danger-outline" ng-click="$ctrl.item.cssRules.splice($index);" title="{{:: ts('Remove style') }}">
     <i class="crm-i fa-ban"></i>
   </button>