@fto-consult/expo-ui 2.27.1 → 2.28.1

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.
@@ -1,8 +1,8 @@
1
1
 
2
2
 
3
3
  import DateLib from "$lib/date";
4
- import {isNonNullString,defaultStr,isNullOrEmpty,debounce,uniqid} from "$utils";
5
- import {regexParser,regexActions,operators as _operators,actions as _actions,periodActions, inActions as _inActions,getFilterStateValues,getSessionData,setSessionData} from "$cfilters";
4
+ import {isNonNullString,defaultStr,isNullOrEmpty,debounce,isFunction,uniqid} from "$utils";
5
+ import {regexParser,regexActions,operators as _operators,actions as _actions,periodActions,betweenActions, inActions as _inActions,getFilterStateValues,getSessionData,setSessionData} from "$cfilters";
6
6
  import {parseDecimal} from "$ecomponents/TextField";
7
7
  import notify from "$notify";
8
8
  import PropTypes from "prop-types";
@@ -16,6 +16,7 @@ import theme from "$theme";
16
16
  import {isMobileMedia} from "$cplatform/dimensions";
17
17
  import { ActivityIndicator } from "react-native-paper";
18
18
  import DialogProvider from "$components/Form/FormData/DialogProvider";
19
+ import FilterBetweenComponent from "./BetweenComponent";
19
20
 
20
21
  const manualRunKey = "manual-run";
21
22
 
@@ -129,10 +130,19 @@ export default class Filter extends AppComponent {
129
130
  this.fireFilterSearch(false);
130
131
  });
131
132
  }
133
+ getDefaultAction(type){
134
+ type = defaultStr(type,this.type,this.props.type).toLowerCase();
135
+ if(type.contains('select')){
136
+ return "$in";
137
+ } if(type !== 'date2time' && type !== 'time' && type !== 'number' && type !== 'decimal'){
138
+ return '$regexcontains';
139
+ }
140
+ return '$eq';
141
+ }
132
142
  initFiltersOp(type){
133
143
  type = defaultStr(type,this.type).toLowerCase();
134
144
  let operators = {..._operators};
135
- let actions = {..._actions};
145
+ let actions = {...betweenActions,..._actions};
136
146
  if(this.props.orOperator === false){
137
147
  delete operators.$or;
138
148
  }
@@ -144,21 +154,19 @@ export default class Filter extends AppComponent {
144
154
  let ignoreCase = this.props.ignoreCase;
145
155
  ignoreCase = defaultVal(ignoreCase,true);
146
156
  let isTextFilter = false;
147
- let defaultAct = '$eq';
148
157
  if(type =="checkbox" || type == 'switch'){
149
158
  action = '$eq';
150
- } else if(type == 'select'){
159
+ } else if(type.contains('select')){
151
160
  actions = _inActions;
152
- defaultAct = "$in";
153
161
  } else if(type == 'date' || type =='datetime') {
154
162
  actions = {...periodActions, ...actions}
163
+ delete actions.$between;
155
164
  } else if(type !== 'date2time' && type !== 'time' && type !== 'number' && type !== 'decimal'){
156
- actions = regexActions;
157
- defaultAct = '$regexcontains';
165
+ actions = {...betweenActions,...regexActions};
158
166
  isTextFilter = true;
159
167
  }
160
168
  if(!action){
161
- action = defaultAct;
169
+ action = this.getDefaultAction(type);
162
170
  }
163
171
  operator = defaultVal(operator,"$and");
164
172
  return {actions,action,ignoreCase,operator,operators,manualRun:defaultBool(this.props.manualRun,false),defaultValue:defaultVal(this.props.defaultValue),isTextFilter};
@@ -248,26 +256,44 @@ export default class Filter extends AppComponent {
248
256
  const t = defaultStr(this.type,this.props.type);
249
257
  return t.contains("date") && t.contains("time");
250
258
  }
251
- showPeriodSelector (success){
259
+ showBetweenSelector(args){
260
+ return this.showBetweenActionSelector(args);
261
+ }
262
+ showPeriodSelector(args){
263
+ return this.showBetweenActionSelector(args);
264
+ }
265
+ showBetweenActionSelector(args){
266
+ if(typeof args =='function'){
267
+ args = {success:args};
268
+ }
269
+ let {success,callback} = defaultObj(args);
270
+ const _type = defaultStr(this.type,this.props.type).toLowerCase().trim();
271
+ success = typeof success =='function'? success : typeof callback =='function'? callback : undefined;
252
272
  const defaultValue = defaultStr(this.state.defaultValue).trim();
253
273
  let split = defaultValue.split("=>");
254
- let isDateTime = this.isDateTime();
255
- let start = isDateTime ? new Date().toSQLDateTimeFormat() : new Date().toSQLDateFormat(), end = start;
256
-
257
- if(DateLib.isValidSQLDateTime(split[0]) || DateLib.isValidSQLDate(split[0])){
258
- start = split[0];
259
- }
260
- if(DateLib.isValidSQLDateTime(split[1]) || DateLib.isValidSQLDate(split[1])){
261
- end = split[1];
262
- }
263
- const type = isDateTime? "datetime" : "date";
264
- DialogProvider.open({
274
+ const isDateTime = this.isDateTime();
275
+ let start = split[0] && split[0] || undefined, end = split[1] && split[1] || undefined;
276
+ const willHandleDate = _type.contains('date');
277
+ if(willHandleDate){
278
+ start = isDateTime ? new Date().toSQLDateTimeFormat() : new Date().toSQLDateFormat();
279
+ end = start;
280
+ if(DateLib.isValidSQLDateTime(split[0]) || DateLib.isValidSQLDate(split[0])){
281
+ start = split[0];
282
+ }
283
+ if(DateLib.isValidSQLDateTime(split[1]) || DateLib.isValidSQLDate(split[1])){
284
+ end = split[1];
285
+ }
286
+ }
287
+ const type = willHandleDate ? (isDateTime? "datetime" : "date"):_type;
288
+ const format = this.props.format;
289
+ return new Promise((resolve,reject)=>{
290
+ DialogProvider.open({
265
291
  subtitle : false,
266
292
  fields : {
267
- start : {type,text:'Du',defaultValue:start},
268
- end : {type,text:'Au',defaultValue:end}
293
+ start : {format,type,text:(willHandleDate?'Du':"Valeur inférieure"),defaultValue:start},
294
+ end : {format,type,text:willHandleDate?'Au':"Valeur supérieure",defaultValue:end}
269
295
  },
270
- title :"Définir une période ["+defaultStr(this.props.label,this.props.text)+"]",
296
+ title :"Définir {0} [{1}]".sprintf(willHandleDate?"une période":"Un intervalle",defaultStr(this.props.label,this.props.text)),
271
297
  cancelButton : true,
272
298
  actions : {
273
299
  yes : {
@@ -276,19 +302,22 @@ export default class Filter extends AppComponent {
276
302
  },
277
303
  },
278
304
  onSuccess : ({data})=>{
279
- if(data.start && data.end && data.start> data.end){
280
- return notify.error("La date de fin doit être supérieure à la date de début");
305
+ if(data.start !== undefined && data.start !== null && data.end !== undefined && data.end !== null && data.start> data.end){
306
+ return notify.error("La {0} doit être supérieure à la {1}".sprintf(willHandleDate?"date de fin":"valeur supérieure",willHandleDate?"date de début":"valeur inférieure"));
281
307
  }
282
- if(isFunction(success)){
308
+ if(typeof(success) =="function"){
283
309
  success(data.start+"=>"+data.end);
284
310
  }
311
+ resolve(data.start+"=>"+data.end);
285
312
  DialogProvider.close();
286
313
  return true;
287
- }})
314
+ }
315
+ })
316
+ })
288
317
  }
289
318
  setAction(action,text){
290
319
  if(!(this.searchFilter.current)) return;
291
- if(action === this.state.action && action !="$period" && action !== "$today" && action !='$yesterday') return;
320
+ if(action === this.state.action && !periodActions[action] && !betweenActions[action]) return;
292
321
  let value = this.state.defaultValue;
293
322
  let act = defaultStr(action).toLowerCase();
294
323
  const isDateTime = this.type?.contains("time");
@@ -297,6 +326,10 @@ export default class Filter extends AppComponent {
297
326
  this.showPeriodSelector((d)=>{
298
327
  this.runAction({value:d,action});
299
328
  })
329
+ } else if(action == '$between'){
330
+ this.showBetweenSelector((d)=>{
331
+ this.runAction({value:d,action});
332
+ })
300
333
  } else if(action =="$today"){
301
334
  return this.runAction({value:new Date().resetHours().resetMinutes().resetSeconds().toFormat(dateFormat),action})
302
335
  } else if(action =="$yesterday"){
@@ -346,7 +379,7 @@ export default class Filter extends AppComponent {
346
379
  })
347
380
  }
348
381
  clearFilter(event){
349
- this.setState({defaultValue:undefined},()=>{
382
+ this.setState({defaultValue:undefined,action:this.getDefaultAction()},()=>{
350
383
  this.callOnValidate();
351
384
  this.fireValueChanged(true);
352
385
  let {onClearFilter,onResetFilter} = this.props;
@@ -356,6 +389,33 @@ export default class Filter extends AppComponent {
356
389
  }
357
390
  })
358
391
  }
392
+ isBetweenAction(action){
393
+ action = defaultStr(action,this.state.action).toLowerCase();
394
+ return !!(this.state.actions && betweenActions[action]);
395
+ }
396
+ isPeriodAction(action){
397
+ action = defaultStr(action,this.state.action).toLowerCase();
398
+ return !!(this.state.actions && periodActions[action]);
399
+ }
400
+ formatValue(value){
401
+ const type = defaultStr(this.type,this.props.type).toLowerCase();
402
+ if(this.isBetweenAction() && isNonNullString(value) && (type ==="number" || type =="decimal")){
403
+ const sp = value.split("=>");
404
+ if(sp.length ==2 && type){
405
+ const format = defaultStr(this.props.format).toLowerCase();
406
+ const v1 = defaultDecimal(parseDecimal(sp[0],type));
407
+ const v2 = defaultDecimal(parseDecimal(sp[1],type));
408
+ return format =="money"? (v1.formatMoney()+"=>"+v2.formatMoney()) : (v1.formatNumber()+"=>"+v2.formatNumber());
409
+ }
410
+ }
411
+ if(typeof value =='number'){
412
+ if(this.props.format =='money'){
413
+ return value.formatMoney();
414
+ }
415
+ return value.formatNumber();
416
+ }
417
+ return value;
418
+ }
359
419
  render (){
360
420
  let {
361
421
  filter,
@@ -442,8 +502,9 @@ export default class Filter extends AppComponent {
442
502
  if(isFunction(filter)){
443
503
  rest.filter = filter;
444
504
  }
445
- const isPeriodAction = this.state.actions && periodActions[this.state.action]
446
- const ignoreDefaultValue = isPeriodAction && isNonNullString(defaultValue) && defaultValue.contains("=>");
505
+ const isPeriodAction = this.isPeriodAction();
506
+ const isBetweenAction = this.isBetweenAction();
507
+ const ignoreDefaultValue = (isPeriodAction||isBetweenAction) && isNonNullString(defaultValue) && defaultValue.contains("=>");
447
508
  rest.defaultValue = defaultValue;
448
509
  rest.disabled = rest.readOnly = rest.affix = false;
449
510
  rest.editable = true;
@@ -500,7 +561,7 @@ export default class Filter extends AppComponent {
500
561
  style : [styles.bold,styles.noVerticalPadding],
501
562
  }:null],
502
563
  ...Object.mapToArray(actions,(x,j)=>{
503
- if(ignoreDefaultValue && !periodActions[j]){
564
+ if(ignoreDefaultValue && !periodActions[j] && !betweenActions[j]){
504
565
  return null;
505
566
  }
506
567
  let checked = j === action?true : false;
@@ -523,7 +584,7 @@ export default class Filter extends AppComponent {
523
584
  }
524
585
 
525
586
  if(!hasS){
526
- x = x+" <"+defaultValue+">"
587
+ x = x+" <"+this.formatValue(defaultValue)+">"
527
588
  }
528
589
  }
529
590
  return {
@@ -539,10 +600,10 @@ export default class Filter extends AppComponent {
539
600
  const containerProps = defaultObj(this.props.containerProps,rest.containerProps);
540
601
  delete rest.containerProps;
541
602
  rest.onValidate = this.onFilterValidate.bind(this);
542
- const Component = this.Component;
603
+ const Component = isBetweenAction ? FilterBetweenComponent : this.Component;
543
604
  const responsiveProps = Object.assign({},responsiveProps);
544
605
  responsiveProps.style = [theme.styles.w100,responsiveProps.style]
545
- if(ignoreDefaultValue) {
606
+ if(ignoreDefaultValue && isPeriodAction) {
546
607
  rest.isPeriodAction = true;
547
608
  }
548
609
  return <View testID={testID+"_FilterContainer"} {...containerProps} style={StyleSheet.flatten([theme.styles.w100,containerProps.style])}>
@@ -4,7 +4,7 @@ import {classExtends,isFunction,isNonNullString,defaultStr,defaultObj,defaultVal
4
4
  import {warning,Forms} from "./utils";
5
5
  import Action from "./Action";
6
6
  import View from "$ecomponents/View";
7
- import KeyboardAvoidingView from "./KeyboardAvoidingView";
7
+ import KeyboardAvoidingView from "$ecomponents/KeyboardAvoidingView";
8
8
  import { StyleSheet } from "react-native";
9
9
  import APP from "$capp/instance";
10
10
  import PropTypes from "prop-types";
@@ -8,7 +8,4 @@ export {default as Form} from "./Form";
8
8
 
9
9
  export {default as Action} from "./Action";
10
10
 
11
- export {default as KeyboardAvoidingView} from "./KeyboardAvoidingView";
12
-
13
-
14
11
  export * from "./utils";