forked from ukrbublik/react-awesome-query-builder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqueryBuilder.js
163 lines (142 loc) · 4.36 KB
/
queryBuilder.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import {defaultValue} from "../utils/stuff";
import {getFieldConfig, getOperatorConfig} from "../utils/configUtils";
import {defaultConjunction} from "../utils/defaultUtils";
import {formatFieldName} from "../utils/ruleUtils";
import {completeValue} from "../utils/funcUtils";
import {Map} from "immutable";
/*
Build tree to http://querybuilder.js.org/ like format
Example:
{
"condition": "AND",
"rules": [
{
"id": "price",
"field": "price",
"type": "double",
"input": "text",
"operator": "less",
"value": "10.25"
},
{
"condition": "OR",
"rules": [
{
"id": "category",
"field": "category",
"type": "integer",
"input": "select",
"operator": "equal",
"value": "2"
},
{
"id": "category",
"field": "category",
"type": "integer",
"input": "select",
"operator": "equal",
"value": "1"
}
]
}
]
}
*/
export const queryBuilderFormat = (item, config) => {
//meta is mutable
let meta = {
usedFields: []
};
const res = formatItem(item, config, meta);
if (!res)
return undefined;
return {
...res,
...meta
};
};
const formatItem = (item, config, meta) => {
if (!item) return undefined;
const type = item.get("type");
const children = item.get("children1");
if ((type === "group" || type === "rule_group") && children && children.size) {
return formatGroup(item, config, meta);
} else if (type === "rule") {
return formatRule(item, config, meta);
}
return undefined;
};
const formatGroup = (item, config, meta) => {
const properties = item.get("properties") || new Map();
const children = item.get("children1");
const id = item.get("id");
const list = children
.map((currentChild) => formatItem(currentChild, config, meta))
.filter((currentChild) => typeof currentChild !== "undefined");
if (!list.size)
return undefined;
let conjunction = properties.get("conjunction");
if (!conjunction)
conjunction = defaultConjunction(config);
const not = properties.get("not");
const resultQuery = {
id,
rules: list.toList(),
condition: conjunction.toUpperCase(),
not,
};
return resultQuery;
};
const formatRule = (item, config, meta) => {
const properties = item.get("properties") || new Map();
const id = item.get("id");
const operator = properties.get("operator");
const options = properties.get("operatorOptions");
let field = properties.get("field");
let value = properties.get("value");
let valueSrc = properties.get("valueSrc");
let valueType = properties.get("valueType");
const hasUndefinedValues = value.filter(v => v === undefined).size > 0;
if (field == null || operator == null || hasUndefinedValues)
return undefined;
const fieldDefinition = getFieldConfig(config, field) || {};
const operatorDefinition = getOperatorConfig(config, operator, field) || {};
const fieldType = fieldDefinition.type || "undefined";
const cardinality = defaultValue(operatorDefinition.cardinality, 1);
const typeConfig = config.types[fieldDefinition.type] || {};
const fieldName = formatFieldName(field, config, meta);
if (value.size < cardinality)
return undefined;
if (meta.usedFields.indexOf(field) == -1)
meta.usedFields.push(field);
value = value.toArray();
valueSrc = valueSrc.toArray();
valueType = valueType.toArray();
let values = [];
for (let i = 0 ; i < value.length ; i++) {
const val = {
type: valueType[i],
value: value[i],
};
values.push(val);
if (valueSrc[i] == "field") {
const secondField = value[i];
if (meta.usedFields.indexOf(secondField) == -1)
meta.usedFields.push(secondField);
}
}
let operatorOptions = options ? options.toJS() : null;
if (operatorOptions && !Object.keys(operatorOptions).length)
operatorOptions = null;
let ruleQuery = {
id,
fieldName,
type: fieldType,
input: typeConfig.mainWidget,
operator,
};
if (operatorOptions)
ruleQuery.operatorOptions = operatorOptions;
ruleQuery.values = values;
return ruleQuery;
};