From aff624e3dfcb656c960d6996e019bb4ee5515688 Mon Sep 17 00:00:00 2001 From: colemanw Date: Thu, 16 Nov 2023 20:15:59 -0500 Subject: [PATCH] SearchKit - Support ORDER BY with aggregate functions --- ext/search_kit/ang/crmSearchAdmin.module.js | 4 ++-- .../crmSearchFunction.component.js | 23 +++++++++++-------- .../ang/crmSearchAdmin/crmSearchFunction.html | 3 ++- .../crmSearchFunctionFlag.component.js | 5 ++-- .../crmSearchAdmin/crmSearchFunctionFlag.html | 8 +++---- 5 files changed, 25 insertions(+), 18 deletions(-) diff --git a/ext/search_kit/ang/crmSearchAdmin.module.js b/ext/search_kit/ang/crmSearchAdmin.module.js index 1b9adf9ffd..c1c8f9fbcf 100644 --- a/ext/search_kit/ang/crmSearchAdmin.module.js +++ b/ext/search_kit/ang/crmSearchAdmin.module.js @@ -190,7 +190,7 @@ function getKeyword(whitelist) { var keyword; _.each(_.filter(whitelist), function(flag) { - if (argString.indexOf(flag + ' ') === 0) { + if (argString.indexOf(flag + ' ') === 0 || argString === flag) { keyword = flag; argString = _.trim(argString.substr(flag.length)); return false; @@ -241,7 +241,7 @@ } getKeyword([',']); } - if (expr && !_.isEmpty(expr.flag_after)) { + if (info.args.length && !_.isEmpty(param.flag_after)) { _.last(info.args).flag_after = getKeyword(_.keys(param.flag_after)); } } else if (param.flag_before && !param.optional) { diff --git a/ext/search_kit/ang/crmSearchAdmin/crmSearchFunction.component.js b/ext/search_kit/ang/crmSearchAdmin/crmSearchFunction.component.js index 366bb69105..25e472b5b3 100644 --- a/ext/search_kit/ang/crmSearchAdmin/crmSearchFunction.component.js +++ b/ext/search_kit/ang/crmSearchAdmin/crmSearchFunction.component.js @@ -44,19 +44,20 @@ } }); - this.addArg = function(exprType) { + this.addArg = function(exprType, optional) { var param = ctrl.getParam(ctrl.args.length), val = ''; if (exprType === 'SqlNumber') { // Number: default to 0 val = 0; - } else if (exprType === 'SqlField') { + } else if (exprType === 'SqlField' && !optional) { // Field: Default to first available field, making it easier to delete the value val = ctrl.getFields().results[0].children[0].id; } ctrl.args.push({ type: ctrl.exprTypes[exprType].type, flag_before: _.filter(_.keys(param.flag_before))[0], + flag_after: _.filter(_.keys(param.flag_after))[0], name: param.name, value: val }); @@ -70,11 +71,11 @@ _.each(ctrl.fn.params, function(param, index) { while ( (ctrl.args.length - index < param.min_expr) && - // TODO: Handle named params like "ORDER BY" - !(param.name && param.optional) && + // Exclude 'api_default' params (should not be changed by the user) + !param.api_default && (!param.optional || param.must_be.length === 1) ) { - ctrl.addArg(param.must_be[0]); + ctrl.addArg(param.must_be[0], param.optional); } }); } @@ -144,6 +145,7 @@ ctrl.args.splice(pos, 0, { type: exprType ? ctrl.exprTypes[exprType].type : null, flag_before: _.filter(_.keys(ctrl.fn.params[pos].flag_before))[0], + flag_after: _.filter(_.keys(ctrl.fn.params[pos].flag_after))[0], name: ctrl.fn.params[pos].name, value: exprType === 'SqlNumber' ? 0 : '' }); @@ -152,6 +154,7 @@ // Update fieldArg var fieldParam = ctrl.fn.params[pos]; ctrl.fieldArg.flag_before = _.keys(fieldParam.flag_before)[0]; + ctrl.fieldArg.flag_after = _.keys(fieldParam.flag_after)[0]; ctrl.fieldArg.name = fieldParam.name; initFunction(); } @@ -159,9 +162,10 @@ }; this.changeArg = function(index) { - var val = ctrl.args[index].value; - // Delete empty value - if (index && !val && val !== 0 && ctrl.args.length > ctrl.fn.params[0].min_expr) { + var val = ctrl.args[index].value, + param = ctrl.getParam(index); + // Delete empty value if allowed + if (index && !val && val !== 0 && !param.optional && ctrl.args.length > param.min_expr) { ctrl.args.splice(index, 1); } ctrl.writeExpr(); @@ -178,7 +182,8 @@ var args = _.transform(ctrl.args, function(args, arg, index) { if (arg.value || arg.value === 0 || arg.flag_before) { var prefix = arg.flag_before || arg.name ? (index ? ' ' : '') + (arg.flag_before || arg.name) + (arg.value ? ' ' : '') : (index ? ', ' : ''); - args.push(prefix + (arg.type === 'string' ? JSON.stringify(arg.value) : arg.value)); + var suffix = arg.flag_after ? ' ' + arg.flag_after : ''; + args.push(prefix + (arg.type === 'string' ? JSON.stringify(arg.value) : arg.value) + suffix); } }); // Replace fake function "e" diff --git a/ext/search_kit/ang/crmSearchAdmin/crmSearchFunction.html b/ext/search_kit/ang/crmSearchAdmin/crmSearchFunction.html index 431c2b15d2..08ef094441 100644 --- a/ext/search_kit/ang/crmSearchAdmin/crmSearchFunction.html +++ b/ext/search_kit/ang/crmSearchAdmin/crmSearchFunction.html @@ -4,12 +4,13 @@
- + +