From 645dd48bc461db300ca200d4a97ff0ed97ac005d Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Sun, 25 Jul 2021 02:23:57 -0400 Subject: [PATCH] SearchKit - support additional functions --- Civi/Api4/Query/SqlFunctionDATE.php | 50 +++++++++++++++++++ Civi/Api4/Query/SqlFunctionTIME.php | 50 +++++++++++++++++++ Civi/Api4/Query/SqlFunctionYEAR.php | 50 +++++++++++++++++++ .../crmSearchFunction.component.js | 20 ++++++-- .../ang/crmSearchAdmin/crmSearchFunction.html | 2 +- 5 files changed, 166 insertions(+), 6 deletions(-) create mode 100644 Civi/Api4/Query/SqlFunctionDATE.php create mode 100644 Civi/Api4/Query/SqlFunctionTIME.php create mode 100644 Civi/Api4/Query/SqlFunctionYEAR.php diff --git a/Civi/Api4/Query/SqlFunctionDATE.php b/Civi/Api4/Query/SqlFunctionDATE.php new file mode 100644 index 0000000000..5c198b94f2 --- /dev/null +++ b/Civi/Api4/Query/SqlFunctionDATE.php @@ -0,0 +1,50 @@ + 1, + 'optional' => FALSE, + ], + ]; + } + + /** + * @return string + */ + public static function getTitle(): string { + return ts('Date Only'); + } + + /** + * Ensure is processed as type Date + * + * @see \Civi\Api4\Utils\FormattingUtil::formatOutputValues + * @param string $value + * @param string $dataType + * @return string|array + */ + public function formatOutputValue($value, &$dataType) { + $dataType = 'Date'; + return $value; + } + +} diff --git a/Civi/Api4/Query/SqlFunctionTIME.php b/Civi/Api4/Query/SqlFunctionTIME.php new file mode 100644 index 0000000000..56641345af --- /dev/null +++ b/Civi/Api4/Query/SqlFunctionTIME.php @@ -0,0 +1,50 @@ + 1, + 'optional' => FALSE, + ], + ]; + } + + /** + * @return string + */ + public static function getTitle(): string { + return ts('Time Only'); + } + + /** + * Prevent reformatting + * + * @see \Civi\Api4\Utils\FormattingUtil::formatOutputValues + * @param string $value + * @param string $dataType + * @return string|array + */ + public function formatOutputValue($value, &$dataType) { + $dataType = NULL; + return $value; + } + +} diff --git a/Civi/Api4/Query/SqlFunctionYEAR.php b/Civi/Api4/Query/SqlFunctionYEAR.php new file mode 100644 index 0000000000..6632e6016a --- /dev/null +++ b/Civi/Api4/Query/SqlFunctionYEAR.php @@ -0,0 +1,50 @@ + 1, + 'optional' => FALSE, + ], + ]; + } + + /** + * @return string + */ + public static function getTitle(): string { + return ts('Year Only'); + } + + /** + * Prevent reformatting + * + * @see \Civi\Api4\Utils\FormattingUtil::formatOutputValues + * @param string $value + * @param string $dataType + * @return string|array + */ + public function formatOutputValue($value, &$dataType) { + $dataType = NULL; + return $value; + } + +} diff --git a/ext/search_kit/ang/crmSearchAdmin/crmSearchFunction.component.js b/ext/search_kit/ang/crmSearchAdmin/crmSearchFunction.component.js index 2ebd28e86d..7ea57ecd4b 100644 --- a/ext/search_kit/ang/crmSearchAdmin/crmSearchFunction.component.js +++ b/ext/search_kit/ang/crmSearchAdmin/crmSearchFunction.component.js @@ -24,7 +24,7 @@ $scope.$watch('$ctrl.expr', function(expr) { var fieldInfo = searchMeta.parseExpr(expr); ctrl.path = fieldInfo.path + fieldInfo.suffix; - ctrl.field = fieldInfo.field; + ctrl.field = [fieldInfo.field]; ctrl.fn = !fieldInfo.fn ? '' : fieldInfo.fn.name; ctrl.modifier = fieldInfo.modifier || null; initFunction(); @@ -42,6 +42,7 @@ } } + // On-demand options for dropdown function selector this.getFunctions = function() { var allowedTypes = [], functions = []; if (ctrl.expr && ctrl.field) { @@ -49,17 +50,26 @@ allowedTypes.push('aggregate'); } else { allowedTypes.push('comparison', 'string'); - if (_.includes(['Integer', 'Float', 'Date', 'Timestamp'], ctrl.field.data_type)) { + if (_.includes(['Integer', 'Float', 'Date', 'Timestamp'], ctrl.field[0].data_type)) { allowedTypes.push('math'); } - if (_.includes(['Date', 'Timestamp'], ctrl.field.data_type)) { + if (_.includes(['Date', 'Timestamp'], ctrl.field[0].data_type)) { allowedTypes.push('date'); } } - _.each(allowedTypes, function (type) { + _.each(allowedTypes, function(type) { + var allowedFunctions = _.filter(CRM.crmSearchAdmin.functions, function(fn) { + return fn.category === type && + fn.params.length && + // For now, only support functions that take a single field + fn.params[0].min_expr === 1 && + fn.params[0].max_expr === 1 && + !_.includes(fn.params[0].cant_be, 'SqlField') && + (!fn.params[0].must_be.length || _.includes(fn.params[0].must_be, 'SqlField')); + }); functions.push({ text: allTypes[type], - children: formatForSelect2(_.where(CRM.crmSearchAdmin.functions, {category: type}), 'name', 'title') + children: formatForSelect2(allowedFunctions, 'name', 'title') }); }); } diff --git a/ext/search_kit/ang/crmSearchAdmin/crmSearchFunction.html b/ext/search_kit/ang/crmSearchAdmin/crmSearchFunction.html index 2274f262d9..258433196a 100644 --- a/ext/search_kit/ang/crmSearchAdmin/crmSearchFunction.html +++ b/ext/search_kit/ang/crmSearchAdmin/crmSearchFunction.html @@ -1,5 +1,5 @@
- +