react-awesome-query-builder
react-awesome-query-builder copied to clipboard
Providing Expression Result for Rules for JsonLogic
Is your feature request related to a problem? Please describe.
We want to use this project to create JsonLogic for OpenFeature targeting rules. This means we need to assign a return value to rules.
Valid JsonLogic for this approach:
{
"if": [
{
"==": [
{
"var": "context.product"
},
"test"
]
},
"returnvalue",
"elseValue"
]
}
Describe the solution you'd like
Ideally, we could define each rule's Return-object like a ValueSource.
- To enable it globally, I suggest adding a configuration property.
- We could add a checkbox or something similar to enable it per the rule. We can handle it via the global rule (theoretically, a group could also have a return value, and the subrules/groups would then be unable to return a value.
Describe alternatives you've considered
For simple strings, I could increase the cardinality of each operator and add a manipulation step to the output - but this works for strings when returning strings. and it also works for numbers as numbers. But we would love to return any value.
magic and naive transformation
function transformRule(rule: object): { operator: string; values: object[] | object; returner: object | undefined } {
const operator = Object.keys(rule)[0];
const values = Object.values(rule)[0] as object[] | object;
if (Array.isArray(values)) {
const returner = values.pop();
return { operator, values, returner };
} else {
const subRule = transformRule(Object.values(rule)[0]);
const values: object = { [subRule.operator]: subRule.values };
const returner: object | undefined = subRule.returner;
return { operator, values, returner };
}
}
export function transformLogic(tree: ImmutableTree, config2: Config) {
const logicResult = QbUtils.jsonLogicFormat(tree, config2);
if (logicResult.logic && 'if' in logicResult.logic) {
const rules = logicResult.logic as JsonLogicIf;
const ruleContent: any[] = [];
for (const rule of rules.if) {
const { operator, values, returner } = transformRule(rule);
const newRule = {
[operator]: values,
};
ruleContent.push(newRule);
if (returner) ruleContent.push(returner);
}
ruleContent.push('elseValue');
logicResult.logic = { if: ruleContent } as JsonLogicIf;
}
return logicResult;
}
Additional context
So far, I like this query builder's flexibility; it is excellent and easy to configure.
This is not a feature request on its own; I can tackle this and take a look at it. The question is, is it feasible and desirable? Also, let me know your take on this. Furthermore, if you think it is not suited for this tool. Can you think of a solution where I'll not fork the whole repository but would manipulate desired parts? (eg. There is no container factory currently in the settings, so I can't overwrite it - coming from the java world, sorry if that would be easy)
Things I am not sure about:
- how to handle the else value
- Is it a desired feature?
Looking forward to the discussions
I thought a little bit more about it and even played around. And my suggested approach has changed :)
- I would add a field on the Group Container level (handled like the values and reusing the widget, if possible).
- Enabling it via a setting in the Behaviour settings, which also defines the "resultType" and "ResultSrc". (Theoretically, we could also enable it per Conjunction if that makes sense.)
- Initially, I would only focus on JsonLogic to be working and available. I am unsure if this is needed for SQL or other formats, but your thoughts are welcome.
There is a demonstration of "switch" mode of query builder (like switch-case, or if-then-else)
https://ukrbublik.github.io/react-awesome-query-builder/#/switch
You can also try locally: run pnpm i
and open http://localhost:3001/#/switch
What do you think about UI, does it fit your needs? Select on the right side (with options Foo and Bar) can be customized, you can render any component instead of select.
Switch mode is supported for SpEL for now, but I can add support for JsonLogic
this is mighty and aweseom and i missed that totally. We ill take a look, and we will most likely also provide a little PR for JsonLogic to be working with this approach. That is really really cool and i am impressed by the flexibility of this tool, truly awesome :)
Hi @aepfli did you managed to do this MR?