Skip to content

Commit

Permalink
Fixes for dot notation (#960)
Browse files Browse the repository at this point in the history
* Fixed import of fields with dot from JsonLogic

* Fixes export to SpEL to respect `fieldSeparator`
  • Loading branch information
ukrbublik authored Jul 27, 2023
1 parent 40321b2 commit 18fdb14
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 25 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
- Updated type `ItemBuilderProps` (PR #959)
- Fixed drag-n-drop to respect `maxNesting` when moving group into group (PR #959)
- Fix: allow custom conjuction in JsonLogic (issue #317) (PR #959)
- Fixed import of fields with dot from JsonLogic (issue #786) (PR #960)
- Fixes export to SpEL to respect `fieldSeparator` (issue #958) (PR #960)
- 6.4.0
- Functions can be used in LHS with `fieldSources: ["field", "func"]` in `settings`
Thanks @rhallerman1 (PR #900, #896) (issues #287, #250, #344, #336)
Expand Down
6 changes: 3 additions & 3 deletions packages/core/modules/config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1236,7 +1236,7 @@ const settings = {
},

formatSpelField: function (field, parentField, parts, partsExt, fieldDefinition, config) {
let fieldName = partsExt.map(({key, parent}, ind) => {
let fieldName = partsExt.map(({key, parent, fieldSeparator: sep}, ind) => {
if (ind == 0) {
if (parent == "[map]")
return `#this[${this.utils.spelEscape(key)}]`;
Expand All @@ -1248,9 +1248,9 @@ const settings = {
if (parent == "map" || parent == "[map]")
return `[${this.utils.spelEscape(key)}]`;
else if (parent == "class" || parent == "[class]")
return `.${key}`;
return `${sep}${key}`;
else
return `.${key}`;
return `${sep}${key}`;
}
}).join("");
if (fieldDefinition.fieldName) {
Expand Down
5 changes: 3 additions & 2 deletions packages/core/modules/export/mongoDb.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ const formatGroup = (parents, item, config, meta, _not = false, _canWrapExpr = t
const type = item.get("type");
const properties = item.get("properties") || new Map();
const children = item.get("children1") || new List();
const {canShortMongoQuery} = config.settings;
const {canShortMongoQuery, fieldSeparator} = config.settings;
const sep = fieldSeparator;

const hasParentRuleGroup = parents.filter(it => it.get("type") == "rule_group").length > 0;
const parentPath = parents
Expand All @@ -71,7 +72,7 @@ const formatGroup = (parents, item, config, meta, _not = false, _canWrapExpr = t
const not = _not ? !(properties.get("not")) : (properties.get("not"));
const list = children
.map((currentChild) => formatItem(
[...parents, item], currentChild, config, meta, not, mode != "array", mode == "array" ? (f => `$$el.${f}`) : undefined)
[...parents, item], currentChild, config, meta, not, mode != "array", mode == "array" ? (f => `$$el${sep}${f}`) : undefined)
)
.filter((currentChild) => typeof currentChild !== "undefined");
if (!canHaveEmptyChildren && !list.size)
Expand Down
7 changes: 5 additions & 2 deletions packages/core/modules/export/spel.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ const formatGroup = (item, config, meta, parentField = null) => {
const groupField = isRuleGroupArray ? field : parentField;
const groupFieldDef = getFieldConfig(config, groupField) || {};
const isSpelArray = groupFieldDef.isSpelArray;
const {fieldSeparator} = config.settings;

// check op for reverse
let groupOperator = properties.get("operator");
Expand Down Expand Up @@ -177,7 +178,8 @@ const formatGroup = (item, config, meta, parentField = null) => {
let ret;
if (isRuleGroupArray) {
const formattedField = formatField(meta, config, field, parentField);
const getSize = isSpelArray ? ".length" : ".size()";
const sep = fieldSeparator || ".";
const getSize = sep + (isSpelArray ? "length" : "size()");
const fullSize = `${formattedField}${getSize}`;
// https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/expressions.html#expressions-collection-selection
const filteredSize = filter ? `${formattedField}.?[${filter}]${getSize}` : fullSize;
Expand Down Expand Up @@ -431,7 +433,8 @@ const formatField = (meta, config, field, parentField = null) => {
return {
key,
parent,
isSpelVariable
isSpelVariable,
fieldSeparator
};
});
const formattedField = formatFieldFn.call(config.ctx, fieldName, parentField, fieldParts, fieldPartsMeta, fieldDefinition, config);
Expand Down
34 changes: 18 additions & 16 deletions packages/core/modules/import/jsonLogic.js
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ const convertConj = (op, vals, conv, config, not, meta, parentField = null, isRu
parts.slice(0, -1)
.map((f, i, parts) => [...parts.slice(0, i), f])
.map(fp => [fp.join(fieldSeparator), getFieldConfig(config, fp)])
.filter(([_f, fc]) => fc.type == "!group")
.filter(([_f, fc]) => fc?.type == "!group")
);
return [f, Object.keys(ancs)];
})
Expand All @@ -451,7 +451,7 @@ const convertConj = (op, vals, conv, config, not, meta, parentField = null, isRu
let children1 = {};
let groupToId = {};
Object.entries(children).map(([k, v]) => {
if (v.type == "group" || v.type == "rule_group") {
if (v?.type == "group" || v?.type == "rule_group") {
// put as-is
children1[k] = v;
} else {
Expand All @@ -460,7 +460,9 @@ const convertConj = (op, vals, conv, config, not, meta, parentField = null, isRu
const groupField = groupAncestors[groupAncestors.length - 1];
if (!groupField) {
// not in rule_group (can be simple field or in struct) - put as-is
children1[k] = v;
if (v) {
children1[k] = v;
}
} else {
// wrap field in rule_group (with creating hierarchy if need)
let ch = children1;
Expand Down Expand Up @@ -514,19 +516,19 @@ const convertConj = (op, vals, conv, config, not, meta, parentField = null, isRu
};


const topLevelFieldsFilter = (fields) => {
let arr = [...fields].sort((a, b) => (a.length - b.length));
for (let i = 0 ; i < arr.length ; i++) {
for (let j = i + 1 ; j < arr.length ; j++) {
if (arr[j].indexOf(arr[i]) == 0) {
// arr[j] is inside arr[i] (eg. "a.b" inside "a")
arr.splice(j, 1);
j--;
}
}
}
return arr;
};
// const topLevelFieldsFilter = (fields) => {
// let arr = [...fields].sort((a, b) => (a.length - b.length));
// for (let i = 0 ; i < arr.length ; i++) {
// for (let j = i + 1 ; j < arr.length ; j++) {
// if (arr[j].indexOf(arr[i]) == 0) {
// // arr[j] is inside arr[i] (eg. "a.b" inside "a")
// arr.splice(j, 1);
// j--;
// }
// }
// }
// return arr;
// };

const wrapInDefaultConjRuleGroup = (rule, parentField, parentFieldConfig, config, conj) => {
if (!rule) return undefined;
Expand Down
22 changes: 22 additions & 0 deletions packages/tests/specs/QueryWithGroupsAndStructs.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -822,3 +822,25 @@ describe("query with !group mode array", () => {
});

});

//////////////////////////////////////////////////////////////////////////////////////////

describe("query with dot but without !struct", () => {

describe("should handle dot notation when importing from JsonLogic", () => {
export_checks(configs.with_dot_in_field, inits.with_dot_in_field, "JsonLogic", {
"logic": inits.with_dot_in_field,
"spel": inits.spel_with_dot_in_field,
});
});

describe("should handle dot notation when importing from SpEL", () => {
export_checks(configs.with_dot_in_field, inits.spel_with_dot_in_field, "SpEL", {
"logic": inits.with_dot_in_field,
"spel": inits.spel_with_dot_in_field,
});
});

});

//////////////////////////////////////////////////////////////////////////////////////////
11 changes: 11 additions & 0 deletions packages/tests/support/configs.js
Original file line number Diff line number Diff line change
Expand Up @@ -1256,3 +1256,14 @@ export const with_keepInputOnChangeFieldSrc = (BasicConfig) => ({
keepInputOnChangeFieldSrc: true,
}
});

export const with_dot_in_field = (BasicConfig) => ({
...BasicConfig,
fields: {
"number.one": {
label: "Number",
type: "number",
preferWidgets: ["number"],
},
},
});
12 changes: 10 additions & 2 deletions packages/tests/support/inits.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ export const with_struct_and_group = {
{ "!!": { "var": "user.login" } }
]
};

export const with_struct_and_group_mixed_obsolete = {
"and": [
{ "==": [ { "var": "results.slider" }, 22 ] },
Expand Down Expand Up @@ -1067,4 +1067,12 @@ export const tree_with_lhs_toLowerCase2 = {
"conjunction": "AND",
"not": false
}
};
};

export const with_dot_in_field = {
"and": [
{ "==": [ { "var": "number.one" }, 11 ] },
]
};

export const spel_with_dot_in_field = "number.one == 11";

0 comments on commit 18fdb14

Please sign in to comment.