Skip to content

Commit

Permalink
SpEL support (ukrbublik#613)
Browse files Browse the repository at this point in the history
* .

* .

* .

* spelFormatValue

* mongo: fix for empty aggregation

* fix T()

* string: fix empty aggr

* sql: add asyncListValues

* aggr

* #

* func

* ? escape

* fixed escape

* float, array, .?[true]

* #this not needed?

* formatSpelField, isSpel*

* spel2js init

* import1

* typo width

* fix revop

* fix omitBrackets

* use my fork

* .

* fix valueType and unary minus

* group basic

* inline list

* date, datetime

* time

* lint fix

* test fix

* added simple tests

* group fix

* some/all/none

* between

* valueType from field config

* !func

* excludeOperators for type

* fix $contains

* chlog

* Like -> Contains
Moved is_empty, is_null to end of operators list

* fix test

* chlog
.
.

* readme

* add "sh " for win

* ternary1

* ternary 2
.

* .

* .

* parentReordableNodesCnt

* export ?:

* import ternary

* ternary import complete with react-select

* .

* .

* fix

* add case

* !

* lint fix

* tsc fix

* fix add first case

* unsafe warning fix

* demo /switch

* fix

* fix validation

* fix

* .

* logger

* .

* fix import

* add/del default

* getSwitchValues

* lint fix

* .

* .

* lint fix

* fix for npm 7+

* .

* lint fix
.

* Added `Utils._loadFromJsonLogic()` that returns `[tree, errors]` (issue ukrbublik#621)

* return Errors

* useCallback

* .

* fix tests

* .

* fix
  • Loading branch information
ukrbublik authored Feb 4, 2022
1 parent b6be2d7 commit e9996ed
Show file tree
Hide file tree
Showing 59 changed files with 3,421 additions and 405 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
# Changelog
- 5.0.0
- Support of SpEL for import and export. See `loadFromSpel` and `spelFormat` in `Utils` (PR #613)
- Added `excludeOperators` for type config (PR #613)
See `excludeOperators: ["proximity"]` in demo
- Changed export of `not_between` op for text format (`!(num >= 3 && num <= 4)` -> `(num < 3 || num > 4)`) (PR #613)
- Rename `Like` -> `Contains`. Moved `is_empty`, `is_null` to end of operators list (PR #613)
- Support MUI v5 (PR #628)
- Upgraded to React 17. Moved from RHL to react-refresh. Converted demo app to FC. (PR #628)
- Added `Utils._loadFromJsonLogic()` that returns `[tree, errors]` (issue #621)
- 4.10.0
- Support Bootstrap (via `reactstrap`) (PR #604)
- 4.9.0
Expand Down
23 changes: 17 additions & 6 deletions CONFIG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ Optionally you can override some options in basic config or add your own types/w

There are functions for building query string: `formatConj`, `formatValue`, `formatOp`, `formatField`, `formatFunc` which are used for `QbUtils.queryString()`. +
They have common param `isForDisplay` - false by default, true will be used for (https://github.com/ukrbublik/react-awesome-query-builder/#querystring-immutablevalue-config-isfordisplay---string)[`QbUtils.queryString(immutableTree, config, true)`] (see 3rd param true). +
Also there are similar `mongoConj`, `mongoFormatOp`, `mongoFormatValue`, `mongoFunc` for building MongoDb query with `QbUtils.mongodbFormat()`. +
And `sqlFormatConj`, `sqlFormatOp`, `sqlFormatValue`, `sqlFormatReverse`, `sqlFunc` for building SQL where query with `QbUtils.sqlFormat()`. +
Also there are similar `mongoConj`, `mongoFormatOp`, `mongoFormatValue`, `mongoFunc`, `mongoFormatFunc`, `mongoArgsAsObject` for building MongoDb query with `QbUtils.mongodbFormat()`. +
And `sqlFormatConj`, `sqlOp`, `sqlFormatOp`, `sqlFormatValue`, `sqlFormatReverse`, `formatSpelField`, `sqlFunc`, `sqlFormatFunc` for building SQL where query with `QbUtils.sqlFormat()`. +
And `spelFormatConj`, `spelOp`, `spelFormatOp`, `spelFormatValue`, `spelFormatReverse`, `spelFunc`, `spelFormatFunc` for building query in (https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/expressions.html)[Spring Expression Language (SpEL)] with `QbUtils.spelFormat()`. +
And `jsonLogic` for building http://jsonlogic.com[JsonLogic] with `QbUtils.jsonLogicFormat()`. +

TIP: Example: https://github.com/ukrbublik/react-awesome-query-builder/tree/master/examples/demo/config.tsx[`demo config`]
Expand Down Expand Up @@ -447,6 +448,7 @@ where `AND` and `OR` - available conjuctions (logical operators). You can add `N
`children` - list of already formatted queries (strings) to be joined with conjuction
|mongoConj |+ for MongoDB format |https://docs.mongodb.com/manual/reference/operator/query-logical/[Name] of logical operator for MongoDb
|sqlFormatConj |+ for SQL format |See `formatConj`
|spelFormatConj |+ for SpEL format |See `formatConj`
|reversedConj | |Opposite logical operator. +
Can be used to optimize `!(A OR B)` to `!A && !B` (done for MongoDB format)
|===
Expand Down Expand Up @@ -485,15 +487,19 @@ where `AND` and `OR` - available conjuctions (logical operators). You can add `N
`value` - string (already formatted value) for `cardinality==1` -or- `Immutable.List` of strings for `cardinality>1`
|labelForFormat | | |If `formatOp` is missing, `labelForFormat` will be used to join operands when building query string
|mongoFormatOp |+ for MongoDB format | |Function for formatting MongoDb expression, used to join operands into rule. +
`(string field, string op, mixed value, bool useExpr, string valueSrc, string valueType, Object opDef, Object operatorOptions) => object` +
`(string field, string op, mixed value, bool useExpr, string valueSrc, string valueType, Object opDef, Object operatorOptions, Object fieldDef) => object` +
`value` - mixed for `cardinality==1` -or- `Array` for `cardinality>2` +
`useExpr` - true if resulted expression will be wrapped in https://docs.mongodb.com/manual/reference/operator/query/expr/index.html[`{'$expr': {...}}`] (used only if you compare field with another field or function) (you need to use aggregation operators in this case, like https://docs.mongodb.com/manual/reference/operator/aggregation/eq/[$eq (aggregation)] instead of https://docs.mongodb.com/manual/reference/operator/query/eq/[$eq])
|sqlOp |+ for SQL format | |Operator name in SQL
|sqlFormatOp |- for SQL format | |Function for advanced formatting SQL WHERE query if just `sqlOp` is not enough. +
`(string field, string op, mixed value, string valueSrc, string valueType, Object opDef, Object operatorOptions) => object` +
|sqlFormatOp |- for SQL format | |Function for advanced formatting SQL WHERE query when just `sqlOp` is not enough. +
`(string field, string op, mixed value, string valueSrc, string valueType, Object opDef, Object operatorOptions, Object fieldDef) => string` +
`value` - mixed for `cardinality==1` -or- `Array` for `cardinality>2`
|spelOp |+ for SpEL format | |Operator name in SpEL
|spelFormatOp |- for SpEL format | |Function for advanced formatting query in SpEL when just `spelOp` is not enough. +
`(string field, string op, mixed value, string valueSrc, string valueType, Object opDef, Object operatorOptions, Object fieldDef) => string` +
`value` - mixed for `cardinality==1` -or- `Array` for `cardinality>2`
|jsonLogic |+ for http://jsonlogic.com[JsonLogic] | |String (eg. `'<'`) -or- function for advanced formatting +
`(object field, string op, mixed value, Object opDef, Object operatorOptions) => object` +
`(object field, string op, mixed value, Object opDef, Object operatorOptions, Object fieldDef) => object` +
`value` - mixed for `cardinality==1` -or- `Array` for `cardinality>2` +
`field` - already formatted `{"var": <some field>}`
|elasticSearchQueryType |+ for ElasticSearch format | |String (eg. `term`) -or- function `(string valueType) => string` +
Expand Down Expand Up @@ -584,6 +590,8 @@ const {
`(mixed val, Object fieldDef, Object wgtDef, string op, Object opDef) => any`
|sqlFormatValue |- for SQL format |`v => SqlString.escape(v)` |Function for formatting widget's value in SQL WHERE query. +
`(mixed val, Object fieldDef, Object wgtDef, string op, Object opDef) => string`
|spelFormatValue |- for SpEL format | |Function for formatting widget's value in SpEL query. +
`(mixed val, Object fieldDef, Object wgtDef, string op, Object opDef) => string`
|jsonLogic |- for http://jsonlogic.com[JsonLogic] |v => v |Function for formatting widget's value for JsonLogic. +
`(mixed val, Object fieldDef, Object wgtDef, string op, Object opDef) => any`
|elasticSearchFormatValue |- for ElasticSearch format |`v => v` |Function for formatting widget's value for ES query. +
Expand Down Expand Up @@ -694,6 +702,9 @@ To enable this feature set `valueSources` of type to `['value', 'func']` (see be
|sqlFunc |- for SQL format |same as func key |Func name in SQL
|sqlFormatFunc |- for SQL format | |Can be used instead of `sqlFunc`. Function with 1 param - args object `{<arg name> : <arg value>}`, should return formatted function expression string. +
Example: SUM function can be formatted with `({a, b}) => a + " + " + b`
|spelFunc |- for SpEL format |same as func key |Func name in SpEL
|spelFormatFunc |- for SpEL format | |Can be used instead of `spelFunc`. Function with 1 param - args object `{<arg name> : <arg value>}`, should return formatted function expression string. +
Example: SUM function can be formatted with `({a, b}) => a + " + " + b`
|mongoFunc |- for MongoDB format |same as func key |Func name in Mongo
|mongoArgsAsObject | |false |Some functions like https://docs.mongodb.com/manual/reference/operator/aggregation/rtrim/[$rtrim] supports named args, other ones like https://docs.mongodb.com/manual/reference/operator/aggregation/slice/[$slice] takes args as array
|mongoFormatFunc |- for MongoDB format | |Can be used instead of `mongoFunc`. Function with 1 param - args object `{<arg name> : <arg value>}`, should return formatted function expression object.
Expand Down
25 changes: 16 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ See [live demo](https://ukrbublik.github.io/react-awesome-query-builder)
- [Bootstrap](https://reactstrap.github.io/)
- vanilla
(Using another UI framework and custom widgets is possible, see below)
- Export to MongoDb, SQL, [JsonLogic](http://jsonlogic.com), ElasticSearch or your custom format
- Import from [JsonLogic](http://jsonlogic.com)
- Export to MongoDb, SQL, [JsonLogic](http://jsonlogic.com), [SpEL](https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/expressions.html), ElasticSearch or your custom format
- Import from [JsonLogic](http://jsonlogic.com), [SpEL](https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/expressions.html)
- TypeScript support (see [types](/modules/index.d.ts) and [demo in TS](/examples))


Expand All @@ -81,7 +81,7 @@ npm i react-awesome-query-builder --save

For AntDesign widgets only:
```
npm i antd --save
npm i antd @ant-design/icons --save
```

For Material-UI 4 widgets only:
Expand Down Expand Up @@ -229,7 +229,7 @@ class DemoQueryBuilder extends Component {
#### Minimal TypeScript example with function component
([Codesandbox](https://codesandbox.io/s/relaxed-sun-erhnu?file=/src/demo/demo.tsx))
```typescript
import React, { useState } from "react";
import React, { useState, useCallback } from "react";
import { Query, Builder, Utils as QbUtils } from "react-awesome-query-builder";
// types
import {
Expand Down Expand Up @@ -307,22 +307,22 @@ export const Demo: React.FC = () => {
config: config
});

const onChange = (immutableTree: ImmutableTree, config: Config) => {
const onChange = useCallback((immutableTree: ImmutableTree, config: Config) => {
// Tip: for better performance you can apply `throttle` - see `examples/demo`
setState({ tree: immutableTree, config: config });
setState(prevState => { ...prevState, tree: immutableTree, config: config });

const jsonTree = QbUtils.getTree(immutableTree);
console.log(jsonTree);
// `jsonTree` can be saved to backend, and later loaded to `queryValue`
};
}, []);

const renderBuilder = (props: BuilderProps) => (
const renderBuilder = useCallback((props: BuilderProps) => (
<div className="query-builder-container" style={{ padding: "10px" }}>
<div className="query-builder qb-lite">
<Builder {...props} />
</div>
</div>
);
), []);

return (
<div>
Expand Down Expand Up @@ -375,6 +375,7 @@ Props:
- `renderBuilder` - function to render query builder itself. Takes 1 param `props` you need to pass into `<Builder {...props} />`.

*Notes*:
- Please apply `useCallback` for `onChange` and `renderBuilder` for performance reason
- If you put query builder component inside [Material-UI](https://github.com/mui-org/material-ui)'s `<Dialog />` or `<Popover />`, please:
- use prop `disableEnforceFocus={true}` for dialog or popver
- set css `.MuiPopover-root, .MuiDialog-root { z-index: 900 !important; }` (or 1000 for AntDesign v3)
Expand Down Expand Up @@ -419,6 +420,8 @@ Wrapping in `div.query-builder-container` is necessary if you put query builder
Convert query value to MongoDb query object.
#### sqlFormat (immutableValue, config) -> String
Convert query value to SQL where string.
#### spelFormat (immutableValue, config) -> String
Convert query value to [Spring Expression Language (SpEL)](https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/expressions.html).
#### elasticSearchFormat (immutableValue, config) -> Object
Convert query value to ElasticSearch query object.
#### jsonLogicFormat (immutableValue, config) -> {logic, data, errors}
Expand All @@ -427,6 +430,10 @@ Wrapping in `div.query-builder-container` is necessary if you put query builder
- Import:
#### loadFromJsonLogic (jsonLogicObject, config) -> Immutable
Convert query value from [JsonLogic](http://jsonlogic.com) format to internal Immutable format.
#### _loadFromJsonLogic (jsonLogicObject, config) -> [Immutable, errors]
#### loadFromSpel (string, config) -> [Immutable, errors]
Convert query value from [Spring Expression Language (SpEL)](https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/expressions.html) format to internal Immutable format.



### Config format
Expand Down
36 changes: 36 additions & 0 deletions css/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,42 @@ ul.ant-select-selection__rendered {
}
}

/******************************************************************************/
/** CASE_GROUP *********************************************************************/
/******************************************************************************/

.case_group {
border-width: 2px;
}

.switch_group {
& > .group--children {
& > .group-or-rule-container > .group-or-rule {
&::before, &::after {
height: calc(50% + 12px); // for `border-width: 2px`
}
}
}
}

.case_group--body {
display: flex;
flex-direction: row;
margin-top: 10px;
margin-bottom: 10px;

.case_group--children {
flex: auto;
margin-top: 0 !important;
margin-bottom: 0 !important;
}

.case_group--value {
margin-top: 0;
margin-bottom: 0;
margin-right: 10px;
}
}

/******************************************************************************/
/** RULE_GROUP *********************************************************************/
Expand Down
6 changes: 4 additions & 2 deletions examples/demo/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ export default (skin: string) => {
const types: Types = {
...InitialConfig.types,
// examples of overriding
text: {
...InitialConfig.types.text,
excludeOperators: ["proximity"],
},
boolean: merge(InitialConfig.types.boolean, {
widgets: {
boolean: {
Expand Down Expand Up @@ -271,7 +275,6 @@ export default (skin: string) => {
firstName: {
label2: "Username", //only for menu's toggler
type: "text",
excludeOperators: ["proximity"],
fieldSettings: {
validateValue: (val: string, fieldSettings) => {
return (val.length < 10);
Expand All @@ -285,7 +288,6 @@ export default (skin: string) => {
login: {
type: "text",
tableName: "t1", // legacy: PR #18, PR #20
excludeOperators: ["proximity"],
fieldSettings: {
validateValue: (val: string, fieldSettings) => {
return (val.length < 10 && (val === "" || val.match(/^[A-Za-z0-9_-]+$/) !== null));
Expand Down
Loading

0 comments on commit e9996ed

Please sign in to comment.