Skip to content

Commit 7197b1d

Browse files
authored
Extended group support (#328)
4.0
1 parent 2671ef9 commit 7197b1d

File tree

96 files changed

+4167
-2533
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+4167
-2533
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
11
# Changelog
2+
- 4.0.0
3+
- Removed setting `useGroupsAsArrays`.
4+
Instead added field config `mode` for type `!group` with values:
5+
`some` (default, corresponding useGroupsAsArrays = true),
6+
`array` (new, user can choose one of group operators),
7+
`struct` (obsolete, corresponding useGroupsAsArrays = false).
8+
- For type=`!group` and mode=`array`:
9+
- new field configs are available: `conjunctions`, `showNot`, `operators`, `defaultOperator`, `initialEmptyWhere`
10+
- you can use group operators `some`, `none`, `all` or operators with 1 integer opearnd (for count): `equal`, `not_equal`, `less`, `between`, ..
11+
- localization setting `addSubRuleLabel`
12+
- Removed obsolete setting `hideConjForOne`
13+
- (rare) Added field config `fieldName` to override field key for import/export
14+
- (rare) Added field config `jsonLogicVar` and settings `jsonLogic.groupVarKey`, `jsonLogic.altVarKey` to override JsonLogic var key if need
215
- 3.0.0
316
- Added [Material-UI](https://material-ui.com) widgets
417
- 2.2.2

CONFIG.adoc

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,11 @@ Example:
171171
|===
172172
|key |required |default |meaning
173173
|type |+ | |One of types described in link:#configtypes[config.types] or `!struct`/`!group` for complex field +
174-
(use `!struct` for objects, `!group` for arrays) +
175-
(for export of `!group` operator https://docs.mongodb.com/manual/reference/operator/query/elemMatch/[elemMatch] will be used in MongoDb, http://jsonlogic.com/operations.html#all-none-and-some[some] in JsonLogic)
174+
(use `!struct` for objects, `!group` for arrays)
175+
|mode | | |For `!group` type, values are: `some`/`array` +
176+
`some` is light mode (default), at least one subrule should match +
177+
(for export https://docs.mongodb.com/manual/reference/operator/query/elemMatch/[elemMatch] will be used in MongoDb, http://jsonlogic.com/operations.html#all-none-and-some[some] in JsonLogic) +
178+
`array` is extended mode, user can choose one of group operators (`some`/`all`/`none`/`count >/</==/...`)
176179
|subfields |+ for `!struct`/`!group` type | |Config for subfields of complex field (multiple nesting is supported)
177180
|label |+ | |Label to be displayed in field list +
178181
(If not specified, fields's key will be used instead)
@@ -204,6 +207,7 @@ Example:
204207
|funcs | | |If comparing with funcs is enabled for this field (`valueSources` contains `'func'`), you can also limit list of funcs to be compared (by default will be available all funcs from link:#configfuncs[config.funcs] with `returnType` matching field's `type`)
205208
|hideForSelect | |false |If true, field will appear only at right side (when you compare field with another field)
206209
|hideForCompare | |false |If true, field will appear only at left side
210+
|conjunctions, showNot | | | For type=`!group` with mode=`array`. Example: `conjunctions: ['AND'], showNot: false`
207211
|===
208212

209213

@@ -249,7 +253,6 @@ const { FieldCascader, FieldDropdown, FieldTreeSelect } = AntdWidgets;
249253
renderFunc: (props) => <FieldDropdown {...props} />,
250254
canReorder: true,
251255
canRegroup: true,
252-
hideConjForOne: true,
253256
maxNesting: 10,
254257
showLabels: false,
255258
showNot: true,
@@ -289,7 +292,6 @@ Behaviour settings:
289292
|canCompareFieldWithField | |For `<ValueFieldWidget>` - Function for building right list of fields to compare field with field +
290293
`(string leftField, Object leftFieldConfig, string rightField, Object rightFieldConfig) => boolean` +
291294
For type == `select`/`multiselect` you can optionally check `listValues`
292-
|useGroupsAsArrays |true |See https://github.com/ukrbublik/react-awesome-query-builder/issues/246[issue]
293295
|===
294296

295297
TIP: For fully read-only mode use these settings:
@@ -318,7 +320,6 @@ Render settings:
318320
Available widgets for AntDesign: `FieldSelect`, `FieldDropdown`
319321
|renderConjs, renderButton, renderButtonGroup, renderProvider, renderValueSources, renderConfirm, useConfirm, renderRuleError | |Other internal render functions you can override if using another UI framework (https://github.com/ukrbublik/react-awesome-query-builder/blob/master/modules/config/antd.js#L47[example])
320322
|showLabels |false |Show labels above all fields?
321-
|hideConjForOne |true |Don't show conjunctions switcher for only 1 rule?
322323
|maxLabelsLength |100 |To shorten long labels of fields/values (by length, i.e. number of chars)
323324
|dropdownPlacement |`bottomLeft` |Placement of antdesign's https://ant.design/components/dropdown/[dropdown] pop-up menu
324325
|customFieldSelectProps |`{}` |You can pass props to `Select` field widget. Example: `{showSearch: true}`
@@ -348,6 +349,12 @@ Other settings:
348349
`parts` - list of fields's keys for struct field +
349350
`label2` - field's `label2` OR parts joined by `fieldSeparatorDisplay` +
350351
Default impl will just return `field` (or `label2` for `isForDisplay==true`)
352+
|formatAggr | |Function for formatting query string, used to format aggregation rule (like `SOME OF Cars HAVE Year > 2010`) +
353+
`(string whereStr, string aggrField, string operator, mixed value, string valueSrc, string valueType, Object operatorDefinition, Object operatorOptions, bool isForDisplay, Object aggrFieldDef) => string` +
354+
`whereStr` - formatted string representing condition for items (eg. `Year > 2010` in example) +
355+
`aggrField` - aggregation field (eg. `Cars` in example) +
356+
`operator` - can be `some`/`all`/`none` (with cardinality 0) or `equal`/`less`/`between`/.. (applied to count of items) +
357+
`value` - for operators with cardinality 1/2 it is value for comparing with count of items
351358
|fieldSeparator |`.` |Separator for struct fields.
352359
|fieldSeparatorDisplay |`.` |Separator for struct fields in UI.
353360
|===
@@ -369,6 +376,7 @@ Localization:
369376
|delGroupLabel |`null`
370377
|addGroupLabel |Add group
371378
|addRuleLabel |Add rule
379+
|addSubRuleLabel |Add sub rule
372380
|notLabel |Not
373381
|valueSourcesPopupTitle |Select value source
374382
|removeRuleConfirmOptions |If you want to ask confirmation of removing non-empty rule/group, add these options. +

css/styles.scss

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ ul.ant-select-selection__rendered {
239239

240240
.group--drag-handler {
241241
margin-right: 8px;
242+
position: relative;
243+
top: 3px;
242244
}
243245
.group--conjunctions {
244246
.group--drag-handler {
@@ -324,6 +326,16 @@ ul.ant-select-selection__rendered {
324326
}
325327
}
326328

329+
/******************************************************************************/
330+
/** RULE_GROUP_EXT *********************************************************************/
331+
/******************************************************************************/
332+
333+
.group--header.hide--drag.with--conjs {
334+
& > .group--field--count--rule {
335+
margin-left: 20px;
336+
}
337+
}
338+
327339
/******************************************************************************/
328340
/** RULE **********************************************************************/
329341
/******************************************************************************/
@@ -545,7 +557,7 @@ $rule_func_items: ".rule--func--wrapper", ".rule--func", ".rule--func--args", ".
545557
}
546558

547559
$group_actions: ".group--drag-handler", ".group--actions";
548-
$inactive_conjs: ".group--conjunctions .ant-btn:not(.ant-btn-primary)";
560+
$inactive_conjs: ".group--conjunctions .ant-btn:not(.ant-btn-primary)", ".rule_group_ext--drag-handler";
549561
$active_conjs: ".group--conjunctions .ant-btn.ant-btn-primary";
550562
$rule_actions: ".widget--valuesrc", ".rule--drag-handler", ".rule--header";
551563

@@ -573,7 +585,7 @@ $rule_actions: ".widget--valuesrc", ".rule--drag-handler", ".rule--header";
573585
.group--footer {
574586
padding: {
575587
left: 10px;
576-
right: 5px;
588+
right: 10px;
577589
}
578590
margin: {
579591
top: 10px;

examples/demo/config.tsx

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ export default (skin) => {
168168
deleteLabel: null,
169169
addGroupLabel: "Add group",
170170
addRuleLabel: "Add rule",
171+
addSubRuleLabel: "Add sub rule",
171172
delGroupLabel: null,
172173
notLabel: "Not",
173174
valueSourcesPopupTitle: "Select value source",
@@ -237,7 +238,7 @@ export default (skin) => {
237238
},
238239
login: {
239240
type: "text",
240-
tableName: "t1", // PR #18, PR #20
241+
tableName: "t1", // legacy: PR #18, PR #20
241242
excludeOperators: ["proximity"],
242243
fieldSettings: {
243244
validateValue: (val, fieldSettings) => {
@@ -272,6 +273,49 @@ export default (skin) => {
272273
}
273274
}
274275
},
276+
cars: {
277+
label: "Cars",
278+
type: "!group",
279+
mode: "array",
280+
conjunctions: ["AND", "OR"],
281+
showNot: true,
282+
operators: [
283+
// w/ operand - count
284+
"equal",
285+
"not_equal",
286+
"less",
287+
"less_or_equal",
288+
"greater",
289+
"greater_or_equal",
290+
"between",
291+
"not_between",
292+
293+
// w/o operand
294+
"some",
295+
"all",
296+
"none",
297+
],
298+
defaultOperator: "some",
299+
initialEmptyWhere: true, // if default operator is not some/all/none, true - to set no children, false - to add 1 empty
300+
301+
subfields: {
302+
vendor: {
303+
type: "select",
304+
fieldSettings: {
305+
listValues: ["Ford", "Toyota", "Tesla"],
306+
},
307+
valueSources: ["value"],
308+
},
309+
year: {
310+
type: "number",
311+
fieldSettings: {
312+
min: 1990,
313+
max: 2020,
314+
},
315+
valueSources: ["value"],
316+
}
317+
}
318+
},
275319
prox1: {
276320
label: "prox",
277321
tooltip: "Proximity search",

examples/demo/demo.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ const loadedConfig = loadConfig(initialSkin);
2020
let initValue: JsonTree = loadedInitValue && Object.keys(loadedInitValue).length > 0 ? loadedInitValue as JsonTree : emptyInitValue;
2121
const initLogic: JsonLogicTree = loadedInitLogic && Object.keys(loadedInitLogic).length > 0 ? loadedInitLogic as JsonLogicTree : undefined;
2222
let initTree;
23-
initTree = checkTree(loadTree(initValue), loadedConfig);
24-
//initTree = checkTree(loadFromJsonLogic(initLogic, loadedConfig), loadedConfig); // <- this will work same
23+
//initTree = checkTree(loadTree(initValue), loadedConfig);
24+
initTree = checkTree(loadFromJsonLogic(initLogic, loadedConfig), loadedConfig); // <- this will work same
2525

2626
const updateEvent = new CustomEvent("update", { detail: {
2727
config: loadedConfig,

examples/demo/init_logic.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,78 @@ export default
3131
},
3232
35
3333
]
34+
},
35+
{
36+
"some": [
37+
{
38+
"var": "results"
39+
},
40+
{
41+
"and": [
42+
{
43+
"==": [
44+
{
45+
"var": "product"
46+
},
47+
"abc"
48+
]
49+
},
50+
{
51+
">": [
52+
{
53+
"var": "score"
54+
},
55+
8
56+
]
57+
}
58+
]
59+
}
60+
]
61+
},
62+
{
63+
">": [
64+
{
65+
"reduce": [
66+
{
67+
"filter": [
68+
{
69+
"var": "cars"
70+
},
71+
{
72+
"and": [
73+
{
74+
"==": [
75+
{
76+
"var": "vendor"
77+
},
78+
"Toyota"
79+
]
80+
},
81+
{
82+
">=": [
83+
{
84+
"var": "year"
85+
},
86+
2010
87+
]
88+
}
89+
]
90+
}
91+
]
92+
},
93+
{
94+
"+": [
95+
1,
96+
{
97+
"var": "accumulator"
98+
}
99+
]
100+
},
101+
0
102+
]
103+
},
104+
2
105+
]
34106
}
35107
]
36108
};

examples/demo/init_value.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ export default
2424
],
2525
"valueType": [
2626
"text"
27+
],
28+
"valueError": [
29+
null
2730
]
2831
}
2932
},
@@ -40,6 +43,9 @@ export default
4043
],
4144
"valueType": [
4245
"boolean"
46+
],
47+
"valueError": [
48+
null
4349
]
4450
}
4551
},
@@ -56,6 +62,9 @@ export default
5662
],
5763
"valueType": [
5864
"number"
65+
],
66+
"valueError": [
67+
null
5968
]
6069
}
6170
},
@@ -79,6 +88,9 @@ export default
7988
],
8089
"valueType": [
8190
"select"
91+
],
92+
"valueError": [
93+
null
8294
]
8395
}
8496
},
@@ -93,6 +105,70 @@ export default
93105
"valueSrc": [
94106
"value"
95107
],
108+
"valueType": [
109+
"number"
110+
],
111+
"valueError": [
112+
null
113+
]
114+
}
115+
}
116+
}
117+
},
118+
"a99a9b9b-cdef-4012-b456-7175a7d54553": {
119+
"type": "rule_group",
120+
"properties": {
121+
"mode": "array",
122+
"operator": "greater",
123+
"valueType": [
124+
"number"
125+
],
126+
"value": [
127+
2
128+
],
129+
"valueSrc": [
130+
"value"
131+
],
132+
"conjunction": "AND",
133+
"valueError": [
134+
null
135+
],
136+
"field": "cars"
137+
},
138+
"children1": {
139+
"99a9a9a8-89ab-4cde-b012-3175a7d55374": {
140+
"type": "rule",
141+
"properties": {
142+
"field": "cars.vendor",
143+
"operator": "select_equals",
144+
"value": [
145+
"Toyota"
146+
],
147+
"valueSrc": [
148+
"value"
149+
],
150+
"valueError": [
151+
null
152+
],
153+
"valueType": [
154+
"select"
155+
]
156+
}
157+
},
158+
"988bbbab-4567-489a-bcde-f175a7d58793": {
159+
"type": "rule",
160+
"properties": {
161+
"field": "cars.year",
162+
"operator": "greater_or_equal",
163+
"value": [
164+
2010
165+
],
166+
"valueSrc": [
167+
"value"
168+
],
169+
"valueError": [
170+
null
171+
],
96172
"valueType": [
97173
"number"
98174
]

0 commit comments

Comments
 (0)