ukrbublik / react-awesome-query-builder

User-friendly query builder for React
https://ukrbublik.github.io/react-awesome-query-builder
MIT License
1.91k stars 490 forks source link

Group misses "Not" conjunction when rendered with saved JsonLogic #1059

Closed Ketler13 closed 1 week ago

Ketler13 commented 3 weeks ago

Describe the bug This happens in 5.1.2 and 5.4.2 (latest 5 I believe). If I create nested group with "Not" conjunction, store generated JsonLogic and then try to render that logic after page refresh whole Conjunctions header is missing.

To Reproduce Create a query similar to this:

Screenshot 2024-06-10 at 12 23 52

Output JsonLogic will be: { "and": [ { "==": [ { "var": "user.firstName" }, "a" ] }, { "!": { "some": [ { "var": "results" }, { "==": [ { "var": "score" }, 1 ] } ] } } ] }

After page refresh that logic will be rendered as:

Screenshot 2024-06-10 at 12 24 44

Expected behavior Query should be rendered in a way it was created.

Additional context I also found small difference in generated JsonLogic. Example above has JsonLogic created from scratch. If I then try to load that json (with "Not" disappeared) and change value from 1 to 2 for example:

Screenshot 2024-06-10 at 12 29 17

I'll receive different structure where "!" does not exist anymore as well. { "and": [ { "==": [ { "var": "user.firstName" }, "a" ] }, { "some": [ { "var": "results" }, { "!=": [ { "var": "score" }, 2 ] } ] } ] }

In case I query 2 subfields of the Results object:

Screenshot 2024-06-10 at 12 38 36

I got this JsonLogic: { and: [ { '==': [ { var: 'user.firstName', }, 'a', ], }, { '!': { some: [ { var: 'results', }, { and: [ { '==': [ { var: 'product', }, 'abc', ], }, { '==': [ { var: 'score', }, 1, ], }, ], }, ], }, }, ], }

Then when I render it conjunction is missing as well:

Screenshot 2024-06-10 at 12 39 59

and now "!" exists in json but is moved couple of levels down: { "and": [ { "==": [ { "var": "user.firstName" }, "a" ] }, { "some": [ { "var": "results" }, { "!": { "and": [ { "==": [ { "var": "product" }, "abc" ] }, { "==": [ { "var": "score" }, 1 ] } ] } } ] } ] }

ukrbublik commented 3 weeks ago

If group has 1 operator and has "not", flag operator is converted to reversed one. In your example "==" is replaced with "!=" for "score"

Ketler13 commented 3 weeks ago

@ukrbublik thank you for super quick reply, I've added one more case with multiple sub rules. Is it possible to configure that logic somehow to have query appearance consistent across different renders e.g. without transformation of json logic? Thank you

Ketler13 commented 3 weeks ago

@ukrbublik could you please confirm if correct place to work around this problem is somewhere here: https://github.com/ukrbublik/react-awesome-query-builder/blob/2310dd28c1dc0f4f3d9f5259b3e04407a70c1af7/packages/core/modules/import/jsonLogic.js#L673 https://github.com/ukrbublik/react-awesome-query-builder/blob/2310dd28c1dc0f4f3d9f5259b3e04407a70c1af7/packages/core/modules/import/jsonLogic.js#L700

Right now if I change let canRev = true to let canRev = false UI seems to be the same as original one but I'm not quite sure is it a valid way to do stuff. I can see if group has more than one child then everything works as I expect (e.g. no transformation happens under the hood). Maybe that part can be configured with new field in config.

Thank you

ukrbublik commented 3 weeks ago

Yes, you are right

Ketler13 commented 3 weeks ago

It looks like export to json logic may cause this behavior. If I disable check here: https://github.com/ukrbublik/react-awesome-query-builder/blob/af553ef302807bc563f57a9c585335af425f4fe4/modules/export/jsonLogic.js#L119 and it doesn't try to extract nested single child then subsequent page loads seem to be displaying query in original way.

Not sure if it makes sense to make this behavior configurable, just an additional info for someone who faces similar problem.

Thank you