@fto-consult/expo-ui 2.7.13 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +115 -115
- package/src/auth/Login.js +4 -3
- package/src/components/Chart/appexChart/index.js +1 -1
- package/src/components/Chart/index.js +11 -7
- package/src/components/Datagrid/Common/Common.js +6 -3
- package/src/components/Dialog/DropdownAlert/index.js +35 -24
- package/src/components/Fab/Group.js +135 -1
- package/src/components/Filter/index.js +2 -31
- package/src/components/Form/Fields/Field.js +2 -1
- package/src/components/Form/FormData/FormData.js +1 -1
- package/src/components/Icon/Font.js +7 -3
- package/src/components/Link/index.js +8 -3
- package/src/components/Table/index.js +1 -1
- package/src/layouts/Fab/index.js +1 -0
- package/src/navigation/Drawer/items/index.js +1 -1
- package/src/components/Filter/session.js +0 -18
- package/src/components/Filter/utils.js +0 -552
- package/src/screens/NetWork +0 -4
|
@@ -1,552 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import {isNonNullString,defaultStr,defaultArray,isObjOrArray,isObj} from "$utils";
|
|
3
|
-
import DateLib from "$date";
|
|
4
|
-
import mangoParser from "mongo-parse";
|
|
5
|
-
|
|
6
|
-
export const filterTextTypes = ['text','number','email','search','tel','url','password',"id","idfield",'piecefield','piece'];
|
|
7
|
-
|
|
8
|
-
export const regexActions = {
|
|
9
|
-
$regexequals : 'Egal à',
|
|
10
|
-
$regexcontains : 'Contient',
|
|
11
|
-
$regexnotcontains : 'Ne contient pas',
|
|
12
|
-
$regexnotequals : 'Différent de',
|
|
13
|
-
$regexstartswith : 'Commence par',
|
|
14
|
-
$regexendswith : 'Se termine par'
|
|
15
|
-
}
|
|
16
|
-
export const escapeRegexChars = (value)=>{
|
|
17
|
-
//if(value === undefined || value ===null || value === '' || value ==='undefined') return '';
|
|
18
|
-
//value+='';
|
|
19
|
-
if(!isNonNullString(value)) return '';
|
|
20
|
-
let escapeChars = ['!', '^', '$', '(', ')', '[', ']', '{', '}', '?', '+', '*', '.', '/', '\\', '|']
|
|
21
|
-
for(var i in escapeChars){
|
|
22
|
-
value.replace(escapeChars[i],'\\'+escapeChars[i]);
|
|
23
|
-
}
|
|
24
|
-
return value.toString();
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export const getFilterStateValues = (state)=>{
|
|
28
|
-
state = defaultObj(state);
|
|
29
|
-
const r = {};
|
|
30
|
-
['defaultValue','action','actions','operator','operators','ignoreCase','value','manualRun'].map((v)=>{
|
|
31
|
-
r[v] = state[v];
|
|
32
|
-
})
|
|
33
|
-
return r;
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**** si le filtre peut être pris en compte */
|
|
38
|
-
export const canHandleFilter = (f)=>{
|
|
39
|
-
if(!isObj(f)) return false;
|
|
40
|
-
if(!isNonNullString(f.operator) || !isNonNullString(f.action)) {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
if(f.value === undefined || f.value === 'undefined' || f.value ==='' || f.value ===null) {
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
if(f.value instanceof RegExp){
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
49
|
-
if(isObjOrArray(f.value) && Object.size(f.value,true) <=0) return false;
|
|
50
|
-
return true;
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export const regexExpressions = {
|
|
55
|
-
notcontains : {
|
|
56
|
-
left : "^((?!(",
|
|
57
|
-
right : ")).)*$",
|
|
58
|
-
/***@see : https://www.w3schools.com/sql/sql_like.asp */
|
|
59
|
-
sql : (string)=>{
|
|
60
|
-
return "%"+defaultStr(string).ltrim("%").rtrim("%")+"%";
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
notequals : {
|
|
64
|
-
left : "^(?!",
|
|
65
|
-
right : "$).*$",
|
|
66
|
-
},
|
|
67
|
-
equals : {
|
|
68
|
-
left : "/^",
|
|
69
|
-
right : '$/'
|
|
70
|
-
},
|
|
71
|
-
startswith : {
|
|
72
|
-
left : "/^",
|
|
73
|
-
right : '/',
|
|
74
|
-
sql : (string)=>{
|
|
75
|
-
return defaultStr(string).rtrim("%")+"%";
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
endswith : {
|
|
79
|
-
left : "",
|
|
80
|
-
right : '$/',
|
|
81
|
-
sql : (string)=>{
|
|
82
|
-
return "%"+defaultStr(string).ltrim("%");
|
|
83
|
-
}
|
|
84
|
-
},
|
|
85
|
-
contains : {
|
|
86
|
-
left : "/",
|
|
87
|
-
right : '/',
|
|
88
|
-
sql : (string)=>{
|
|
89
|
-
return "%"+defaultStr(string).ltrim("%").rtrim("%")+"%";
|
|
90
|
-
}
|
|
91
|
-
},
|
|
92
|
-
}
|
|
93
|
-
/**** prend en paramètre une chaine de caractère et un nom d'opérateur et génère
|
|
94
|
-
* la chaine de caracètre mango regex correspondant
|
|
95
|
-
*/
|
|
96
|
-
const toMangoRegex = (val,operator)=>{
|
|
97
|
-
if(!isNonNullString(val) || !isNonNullString(operator) || !regexExpressions[operator]) return "";
|
|
98
|
-
const rOp = regexExpressions[operator];
|
|
99
|
-
return rOp.left+escapeRegexChars(val)+rOp.right;
|
|
100
|
-
}
|
|
101
|
-
export const regexParser = {
|
|
102
|
-
equals : (val)=> {
|
|
103
|
-
return toMangoRegex(val,"equals");
|
|
104
|
-
},
|
|
105
|
-
startswith : (val) => {
|
|
106
|
-
return toMangoRegex(val,"startswith");
|
|
107
|
-
},
|
|
108
|
-
endswith : (val) => {
|
|
109
|
-
return toMangoRegex(val,"endswith");
|
|
110
|
-
},
|
|
111
|
-
contains : (val) => {
|
|
112
|
-
return toMangoRegex(val,"contains");
|
|
113
|
-
},
|
|
114
|
-
notequals : (val) => {
|
|
115
|
-
return toMangoRegex(val,"notequals");
|
|
116
|
-
},
|
|
117
|
-
notcontains : (val) =>{
|
|
118
|
-
return toMangoRegex(val,"notcontains");
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
/*** prend une expression regulière et le convertis en operateur, valeur
|
|
122
|
-
* @param {string} la valeur otenue au format regex
|
|
123
|
-
*/
|
|
124
|
-
export const regexDeparser = (regexValue)=>{
|
|
125
|
-
if(!regexValue) return null;
|
|
126
|
-
regexValue = regexValue.toString();
|
|
127
|
-
if(regexValue.endsWith("/i")){
|
|
128
|
-
regexValue = regexValue.rtrim("/i")+"/";
|
|
129
|
-
}
|
|
130
|
-
if(!isNonNullString(regexValue)) return null;
|
|
131
|
-
for(let i in regexExpressions){
|
|
132
|
-
const p = regexExpressions[i];
|
|
133
|
-
let rVal = regexValue.ltrim("/").rtrim("/");
|
|
134
|
-
const pLeft = p.left.ltrim("/"),pRight = p.right.rtrim("/");
|
|
135
|
-
if(rVal.startsWith(pLeft) && rVal.endsWith(pRight)){
|
|
136
|
-
return {
|
|
137
|
-
operator : i,
|
|
138
|
-
value : rVal.ltrim(pLeft).rtrim(pRight),
|
|
139
|
-
regexValue : rVal,
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
export const matchPouchDBOperator = (operator,value)=>{
|
|
146
|
-
if(!isNonNullString(operator)) return null;
|
|
147
|
-
if(!(value) && !isDecimal(value)) return null;
|
|
148
|
-
switch(operator){
|
|
149
|
-
case "MATCH":
|
|
150
|
-
if(isDecimal(value)) value +="";
|
|
151
|
-
return {operator:"$regex",value:RegExp(defaultStr(regexParser.contains(value)).ltrim("/").rtrim("/"),'i')}
|
|
152
|
-
case "NOTMATCH":
|
|
153
|
-
if(isDecimal(value)) value +="";
|
|
154
|
-
return {operator:"$regex",value:RegExp(defaultStr(regexParser.notcontains(value)).ltrim("/").rtrim("/"),'i')}
|
|
155
|
-
case "EQ" :
|
|
156
|
-
return {operator:'$eq',value}
|
|
157
|
-
case "NEQ" :
|
|
158
|
-
return {operator:"$ne",value}
|
|
159
|
-
case "GT":
|
|
160
|
-
return {operator:"$gt",value}
|
|
161
|
-
case "GTE":
|
|
162
|
-
return {operator:"$gte",value}
|
|
163
|
-
case "LT":
|
|
164
|
-
return {operator:"$lt",value}
|
|
165
|
-
case "LTE":
|
|
166
|
-
return {operator:"$lte",value}
|
|
167
|
-
case "IN":
|
|
168
|
-
return {operator:"$in",value}
|
|
169
|
-
case "NOT IN":
|
|
170
|
-
return {operator:"$in",value}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
let Operators = {
|
|
175
|
-
NONE: null,
|
|
176
|
-
MATCH: {
|
|
177
|
-
name: 'contient',
|
|
178
|
-
func: function(value, term) {
|
|
179
|
-
if(value) {
|
|
180
|
-
return value.toString().search(utils.isRegExp(term) ? term : new RegExp(term, 'i')) >= 0;
|
|
181
|
-
} else {
|
|
182
|
-
return !(!!term);
|
|
183
|
-
}
|
|
184
|
-
},
|
|
185
|
-
regexpSupported: true
|
|
186
|
-
},
|
|
187
|
-
NOTMATCH: {
|
|
188
|
-
name: 'ne contient pas',
|
|
189
|
-
func: function(value, term) {
|
|
190
|
-
if(value) {
|
|
191
|
-
return value.toString().search(utils.isRegExp(term) ? term : new RegExp(term, 'i')) < 0;
|
|
192
|
-
} else {
|
|
193
|
-
return !!term;
|
|
194
|
-
}
|
|
195
|
-
},
|
|
196
|
-
regexpSupported: true
|
|
197
|
-
},
|
|
198
|
-
EQ: {
|
|
199
|
-
name: '=',
|
|
200
|
-
func: function(value, term) {
|
|
201
|
-
return value == term;
|
|
202
|
-
},
|
|
203
|
-
regexpSupported: false
|
|
204
|
-
},
|
|
205
|
-
NEQ: {
|
|
206
|
-
name: '<>',
|
|
207
|
-
func: function(value, term) {
|
|
208
|
-
return value != term;
|
|
209
|
-
},
|
|
210
|
-
regexpSupported: false
|
|
211
|
-
},
|
|
212
|
-
GT: {
|
|
213
|
-
name: '>',
|
|
214
|
-
func: function(value, term) {
|
|
215
|
-
return value > term;
|
|
216
|
-
},
|
|
217
|
-
regexpSupported: false
|
|
218
|
-
},
|
|
219
|
-
GTE: {
|
|
220
|
-
name: '>=',
|
|
221
|
-
func: function(value, term) {
|
|
222
|
-
return value >= term;
|
|
223
|
-
},
|
|
224
|
-
regexpSupported: false
|
|
225
|
-
},
|
|
226
|
-
LT: {
|
|
227
|
-
name: '<',
|
|
228
|
-
func: function(value, term) {
|
|
229
|
-
return value < term;
|
|
230
|
-
},
|
|
231
|
-
regexpSupported: false
|
|
232
|
-
},
|
|
233
|
-
LTE: {
|
|
234
|
-
name: '<=',
|
|
235
|
-
func: function(value, term) {
|
|
236
|
-
return value <= term;
|
|
237
|
-
},
|
|
238
|
-
regexpSupported: false
|
|
239
|
-
}
|
|
240
|
-
};
|
|
241
|
-
const utils = {
|
|
242
|
-
ALL: '#All#',
|
|
243
|
-
NONE: '#None#',
|
|
244
|
-
BLANK: '#Blank#"',
|
|
245
|
-
expressionFilter : function(operator, term, staticValue, excludeStatic) {
|
|
246
|
-
var self = this;
|
|
247
|
-
|
|
248
|
-
this.operator = Operators.get(operator);
|
|
249
|
-
this.regexpMode = false;
|
|
250
|
-
this.term = term || null;
|
|
251
|
-
if(this.term && this.operator && this.operator.regexpSupported) {
|
|
252
|
-
if(utils.isRegExp(this.term)) {
|
|
253
|
-
this.regexpMode = true;
|
|
254
|
-
if(!this.term.ignoreCase) {
|
|
255
|
-
this.term = new RegExp(this.term.source, 'i');
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
this.staticValue = staticValue;
|
|
261
|
-
this.excludeStatic = excludeStatic;
|
|
262
|
-
|
|
263
|
-
this.test = function(value) {
|
|
264
|
-
if(Array.isArray(self.staticValue)) {
|
|
265
|
-
var found = self.staticValue.indexOf(value) >= 0;
|
|
266
|
-
return (self.excludeStatic && !found) || (!self.excludeStatic && found);
|
|
267
|
-
} else if(self.term) {
|
|
268
|
-
return self.operator.func(value, self.term);
|
|
269
|
-
} else if(self.staticValue === true || self.staticValue === utils.ALL) {
|
|
270
|
-
return true;
|
|
271
|
-
} else if(self.staticValue === false || self.staticValue === utils.NONE) {
|
|
272
|
-
return false;
|
|
273
|
-
} else {
|
|
274
|
-
return true;
|
|
275
|
-
}
|
|
276
|
-
};
|
|
277
|
-
|
|
278
|
-
this.isAlwaysTrue = function() {
|
|
279
|
-
return !(self.term || Array.isArray(self.staticValue) || self.staticValue === utils.NONE || self.staticValue === false);
|
|
280
|
-
};
|
|
281
|
-
},
|
|
282
|
-
defaultOperator : 'MATCH',
|
|
283
|
-
Operators,
|
|
284
|
-
constants : {},
|
|
285
|
-
items : {
|
|
286
|
-
EQ: Operators.EQ.name,
|
|
287
|
-
MATCH : Operators.MATCH.name,
|
|
288
|
-
NOTMATCH : Operators.NOTMATCH.name,
|
|
289
|
-
NEQ : Operators.NEQ.name,
|
|
290
|
-
GT : Operators.GT.name,
|
|
291
|
-
GTE : Operators.GTE.name,
|
|
292
|
-
LT : Operators.LT.name,
|
|
293
|
-
LTE : Operators.LTE.name
|
|
294
|
-
},
|
|
295
|
-
isRegExp: function(obj) {
|
|
296
|
-
return Object.prototype.toString.apply(obj) === '[object RegExp]';
|
|
297
|
-
},
|
|
298
|
-
/**
|
|
299
|
-
* Escapes all RegExp special characters.
|
|
300
|
-
*/
|
|
301
|
-
escapeRegex: function(re) {
|
|
302
|
-
return re.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
303
|
-
},
|
|
304
|
-
/**** vérifie si la valeur {value}, match la valeur {filterText}
|
|
305
|
-
* @param {object : {
|
|
306
|
-
* value : la valeur à vérifier
|
|
307
|
-
* filterText : le texte à vérifier si value le match
|
|
308
|
-
* operateur : chaine de caractère dans la liste des opérateurs :, props Operators, ci-desous
|
|
309
|
-
* useRegex : Spécifie si l'expression régulière sera utilisée pour la recherche
|
|
310
|
-
* }}
|
|
311
|
-
*/
|
|
312
|
-
match : ({value,filterText,operator,useRegex})=>{
|
|
313
|
-
if(isNonNullString(operator)){
|
|
314
|
-
operator = Operators[operator]
|
|
315
|
-
}
|
|
316
|
-
filterText = defaultStr(filterText);
|
|
317
|
-
operator = defaultObj(operator);
|
|
318
|
-
let isSearchMode = filterText !== '';
|
|
319
|
-
if(operator && isFunction(operator.func)){
|
|
320
|
-
let opterm = operator.regexpSupported && isSearchMode ? (useRegex ? filterText : utils.escapeRegex(filterText)) : filterText;
|
|
321
|
-
return !isSearchMode || operator.func(value, opterm)
|
|
322
|
-
}
|
|
323
|
-
return !isSearchMode ? true : defaultStr(value).toLowerCase().contains(filterText.toLowerCase());
|
|
324
|
-
},
|
|
325
|
-
/**
|
|
326
|
-
* Returns the first element in the array that satisfies the given predicate
|
|
327
|
-
* @param {Array} array the array to search
|
|
328
|
-
* @param {function} predicate Function to apply to each element until it returns true
|
|
329
|
-
* @return {Object} The first object in the array that satisfies the predicate or undefined.
|
|
330
|
-
*/
|
|
331
|
-
findInArray: function(array, predicate) {
|
|
332
|
-
if (this.isArray(array) && predicate) {
|
|
333
|
-
for (var i = 0; i < array.length; i++) {
|
|
334
|
-
var item = array[i];
|
|
335
|
-
if (predicate(item)) {
|
|
336
|
-
return item;
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
return undefined;
|
|
341
|
-
},
|
|
342
|
-
/**
|
|
343
|
-
* Returns a JSON string represenation of an object
|
|
344
|
-
* @param {object} obj
|
|
345
|
-
* @return {string}
|
|
346
|
-
*/
|
|
347
|
-
jsonStringify: function(obj, censorKeywords) {
|
|
348
|
-
function censor(key, value) {
|
|
349
|
-
return censorKeywords && censorKeywords.indexOf(key) > -1 ? undefined : value;
|
|
350
|
-
}
|
|
351
|
-
return JSON.stringify(obj, censor, 2);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
for(let i in utils.items){
|
|
356
|
-
utils.constants[i] = i;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
/*** prend en paramètre un objet de filtres et les prépare pour la requête distante
|
|
360
|
-
* @param {object} filtersToPrepare les filtres à exploiter pour la requête distante
|
|
361
|
-
* le tableau des filtres
|
|
362
|
-
* @param {function|object} filter|options, la méthode utilisée pour effectuer un filtre sur les les élément à prendre en compte
|
|
363
|
-
*
|
|
364
|
-
*/
|
|
365
|
-
export const prepareFilters = (filtersToPrepare,opts)=>{
|
|
366
|
-
if(typeof opts =='function'){
|
|
367
|
-
opts = {filter:opts};
|
|
368
|
-
}
|
|
369
|
-
let {filter,convertToSQL:convToSQL} = opts;
|
|
370
|
-
const filters = {}
|
|
371
|
-
filter = typeof filter =='function'? filter : x=>true;
|
|
372
|
-
Object.map(filtersToPrepare,(f,i)=>{
|
|
373
|
-
if(!isObj(f) || !filter(f) || !isNonNullString(f.operator) || !isNonNullString(f.action)) {
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
|
-
f.field = defaultStr(f.field,i).trim();
|
|
377
|
-
f.action = defaultStr(f.action).toLowerCase().trim();
|
|
378
|
-
if(f.action =="$today"){
|
|
379
|
-
f.operator = "$and";
|
|
380
|
-
f.action = "$eq"
|
|
381
|
-
}
|
|
382
|
-
filters[f.operator] = defaultArray(filters[f.operator]);
|
|
383
|
-
const ob = {};
|
|
384
|
-
ob[f.field] = {}
|
|
385
|
-
if(f.action == "$period"){
|
|
386
|
-
let sp = defaultStr(f.value);
|
|
387
|
-
if(sp){
|
|
388
|
-
sp = sp.split("=>");
|
|
389
|
-
const isValid1 = DateLib.isValidSQLDate(sp[0]) || DateLib.isValidSQLDateTime(sp[0]);
|
|
390
|
-
const isValid2 = DateLib.isValidSQLDate(sp[1]) || DateLib.isValidSQLDateTime(sp[1]);
|
|
391
|
-
if(isValid1 && isValid2){
|
|
392
|
-
filters[f.operator].push({
|
|
393
|
-
[f.field] : {$gte:sp[0]}
|
|
394
|
-
})
|
|
395
|
-
filters[f.operator].push({
|
|
396
|
-
[f.field] : {$lte:sp[1]}
|
|
397
|
-
})
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
} else {
|
|
401
|
-
ob[f.field][f.action] = f.value;
|
|
402
|
-
filters[f.operator].push(ob)
|
|
403
|
-
}
|
|
404
|
-
});
|
|
405
|
-
return convToSQL ? convertToSQL(filters) : filters;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
/*** la liste des actions supportés par les filtres
|
|
409
|
-
* @see : https://github.com/cloudant/mango from mango query mapping
|
|
410
|
-
*
|
|
411
|
-
*/
|
|
412
|
-
export const actions = ["$lt", "$gt", "$lte", "$gte", "$eq", "$exists", "$type", "$in", "$nin", "$all", "$size", "$or", "$nor", "$not", "$mod", "$regex", "$elemMatch"]
|
|
413
|
-
|
|
414
|
-
export default utils;
|
|
415
|
-
|
|
416
|
-
/*** convertis les filtres pris au format mangoesQuey, au format de sortie SQL
|
|
417
|
-
* @see : https://github.com/gordonBusyman/mongo-to-sql-converter
|
|
418
|
-
* @param {object} filters, les filtres au format mango query à convertir au format SQL
|
|
419
|
-
*/
|
|
420
|
-
export const convertToSQL = (filters)=>{
|
|
421
|
-
if(!isObjOrArray(filters)) return [];
|
|
422
|
-
const whereParsed = mangoParser.parse(filters)
|
|
423
|
-
return whereParsed.parts.reduce((prev, curr) => {
|
|
424
|
-
const c = whereClauseToSQL(curr);
|
|
425
|
-
return c ? [...prev,c] : prev;
|
|
426
|
-
}, []).map((filter)=>{
|
|
427
|
-
if(filter.field === MANGO_QUERY_OPERATOR){
|
|
428
|
-
delete filter.field;
|
|
429
|
-
}
|
|
430
|
-
return filter;
|
|
431
|
-
});
|
|
432
|
-
}
|
|
433
|
-
export const MANGO_QUERY_OPERATOR = "MANGO_QUERY_OPERATOR";
|
|
434
|
-
const whereClauseToSQL = (currentMongoParserElement) => {
|
|
435
|
-
let { field, operator, operand } = currentMongoParserElement;
|
|
436
|
-
if(!isNonNullString(operator) || !operatorsMap[operator]) return null;
|
|
437
|
-
operator = operatorsMap[operator]
|
|
438
|
-
if(operator == 'LIKE'){
|
|
439
|
-
const deparsed = regexDeparser(operand);
|
|
440
|
-
if(!isObj(deparsed)){
|
|
441
|
-
return null;
|
|
442
|
-
}
|
|
443
|
-
operand = deparsed.value;
|
|
444
|
-
const deparsedOp = deparsed.operator;
|
|
445
|
-
if(deparsedOp =='notcontains'){
|
|
446
|
-
operator = "NOT LIKE";
|
|
447
|
-
}
|
|
448
|
-
if(deparsedOp =='equals'){
|
|
449
|
-
operator = operatorsMap.$eq;
|
|
450
|
-
} else if(deparsedOp =='notequals'){
|
|
451
|
-
operator = operatorsMap.$ne;
|
|
452
|
-
} else{
|
|
453
|
-
const opMap = regexExpressions[deparsedOp];
|
|
454
|
-
if(!opMap || typeof opMap.sql !=='function') return null;
|
|
455
|
-
operand = opMap.sql(operand);
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
// AND or OR operators with nested elements
|
|
459
|
-
if (typeof field === 'undefined') {
|
|
460
|
-
// parse nested elements
|
|
461
|
-
const nested = operand.reduce((prev, curr) => {
|
|
462
|
-
const parsed = mangoParser.parse(curr);
|
|
463
|
-
const prepared = whereClauseToSQL(parsed.parts[0]);
|
|
464
|
-
if(prepared){
|
|
465
|
-
return [...prev,prepared]
|
|
466
|
-
}
|
|
467
|
-
return prev;
|
|
468
|
-
}, [])
|
|
469
|
-
|
|
470
|
-
// nested WHERE element
|
|
471
|
-
return {
|
|
472
|
-
field: MANGO_QUERY_OPERATOR,
|
|
473
|
-
operator,
|
|
474
|
-
operand: nested
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
// simple WHERE element
|
|
478
|
-
return {
|
|
479
|
-
field,
|
|
480
|
-
operator,
|
|
481
|
-
operand
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
// map mongoDB -> SQL operators
|
|
486
|
-
const operatorsMap = {
|
|
487
|
-
$or: 'OR',
|
|
488
|
-
$and: 'AND',
|
|
489
|
-
$lt: '<',
|
|
490
|
-
$lte: '<=',
|
|
491
|
-
$gt: '>',
|
|
492
|
-
$gte: '>=',
|
|
493
|
-
$ne: '!=',
|
|
494
|
-
$in: 'IN',
|
|
495
|
-
$nin : 'NOT IN',
|
|
496
|
-
$eq: '=',
|
|
497
|
-
$regex : "LIKE"
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
/**
|
|
501
|
-
*
|
|
502
|
-
* @param {*} operand
|
|
503
|
-
* @param {*} operator
|
|
504
|
-
* @param {*} field
|
|
505
|
-
*
|
|
506
|
-
* Return the operand in right format
|
|
507
|
-
*/
|
|
508
|
-
export const getTyppedOperand = (operand, operator, field) => {
|
|
509
|
-
if (typeof operand === 'string') { // wrap strings in double quots
|
|
510
|
-
return "'" +(operand) + "'"
|
|
511
|
-
} else if (operator === 'IN' || operator =='NOT IN') { // wrap IN arguments in brackers
|
|
512
|
-
operand = Array.isArray(operand)? operand.map(op => getTyppedOperand(op, null, null))
|
|
513
|
-
.join(', '): operand;
|
|
514
|
-
return '(' + operand + ')'
|
|
515
|
-
} else if (!isNonNullString(field) && Array.isArray(operand)) { // AND or OR elements
|
|
516
|
-
// recursively call 'buildWhereElement' for nested elements
|
|
517
|
-
// join each element with operator AND or OR
|
|
518
|
-
return operand.reduce((prev, curr) => {
|
|
519
|
-
return [...prev, buildWhereElement(curr)]
|
|
520
|
-
}, []).join(' ' + operator + ' ')
|
|
521
|
-
} else {
|
|
522
|
-
return operand
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
/**
|
|
527
|
-
*
|
|
528
|
-
* @param {*} elem
|
|
529
|
-
*
|
|
530
|
-
* Return element of WHERE clause
|
|
531
|
-
*/
|
|
532
|
-
export const buildWhereElement = (elem) => {
|
|
533
|
-
const { field, operator, operand } = elem
|
|
534
|
-
if (!isNonNullString(field)) { // nested WHERE element
|
|
535
|
-
return '(' + getTyppedOperand(operand, operator, field) + ')'
|
|
536
|
-
} else { // simple WHERE element
|
|
537
|
-
return field + ' ' + operator + ' ' + getTyppedOperand(operand, operator, field)
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
/**** construit une requête Where à partir des filtres préparé dans le tableau whereClausePrepared
|
|
542
|
-
* @see : https://github.com/gordonBusyman/mongo-to-sql-converter
|
|
543
|
-
* @parm {array} whereClausePrepared, les filtres préparés avec la méthode prepareFilters puis convertis avec la fonction convertToSQL
|
|
544
|
-
@return {string}, la requête Where correspondante
|
|
545
|
-
*/
|
|
546
|
-
export const buildWhere = (whereClausePrepared)=>{
|
|
547
|
-
if(!Array.isArray(whereClausePrepared)) return null;
|
|
548
|
-
// build WHERE string clause by adding each element of array to it, separated with AND
|
|
549
|
-
return whereClausePrepared.reduce((prev, curr) => [
|
|
550
|
-
...prev, buildWhereElement(curr)
|
|
551
|
-
], []).join(' AND ');
|
|
552
|
-
}
|
package/src/screens/NetWork
DELETED