@fto-consult/expo-ui 2.2.3 → 2.3.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/index.js CHANGED
@@ -1,5 +1,11 @@
1
- import { registerRootComponent } from 'expo';
1
+ import { registerRootComponent } from "expo";
2
+ import {Platform } from 'react-native';
3
+ import { createRoot } from 'react-dom/client';
2
4
  import appConfig from "$capp/config";
5
+ import { activateKeepAwake } from 'expo-keep-awake';
6
+ if (__DEV__) {
7
+ activateKeepAwake();
8
+ }
3
9
 
4
10
  /**** initialise l'application expoUI avec les paramètres de configuration
5
11
  * les options sont de la forme :
@@ -10,5 +16,11 @@ import appConfig from "$capp/config";
10
16
  export default function ExpoUIApp (options){
11
17
  options = options && typeof options =='object' && !Array.isArray(options)? options : {};
12
18
  appConfig.current = options.config;
13
- registerRootComponent(require('./src/App').default(options));
14
- }
19
+ const App = require('./src/App').default(options);
20
+ if (Platform.OS === "web") {
21
+ const root = createRoot(document.getElementById("root") ?? document.getElementById("main"));
22
+ root.render(<App />);
23
+ } else {
24
+ registerRootComponent(App);
25
+ }
26
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fto-consult/expo-ui",
3
- "version": "2.2.3",
3
+ "version": "2.3.0",
4
4
  "description": "Bibliothèque de composants UI Expo,react-native",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -62,7 +62,7 @@
62
62
  "@expo/html-elements": "^0.2.0",
63
63
  "@expo/metro-config": "^0.4.0",
64
64
  "@expo/webpack-config": "^0.17.2",
65
- "@fto-consult/common": "^1.11.3",
65
+ "@fto-consult/common": "^1.11.13",
66
66
  "@gorhom/portal": "^1.0.14",
67
67
  "@react-native-async-storage/async-storage": "~1.17.3",
68
68
  "@react-native-community/datetimepicker": "6.5.2",
@@ -12,6 +12,7 @@ import Icon from "$ecomponents/Icon";
12
12
  import {StyleSheet,View} from "react-native";
13
13
  import DatePickerModal from '../DatePickerModal'
14
14
  import "../i18n";
15
+ import PeriodActionComponent from "../PeriodAction";
15
16
 
16
17
  const validMinDate = (date,minDate)=>{
17
18
  if(!minDate || !date) return true;
@@ -44,9 +45,23 @@ const DatePickerInput = React.forwardRef(({
44
45
  style,
45
46
  anchorProps,
46
47
  render_filter,
48
+ isPeriodAction,
49
+ isFilter,
47
50
  calendarIconBefore = false, //si l'icone calendar sera en position left où non
48
51
  ...rest
49
52
  },ref)=>{
53
+ let right = customRight,left = customLeft, isIconLeft = calendarIconBefore;
54
+ if(!isPeriodAction){
55
+ isPeriodAction = isNonNullString(defaultValue) && defaultValue.contains("=>");
56
+ }
57
+ if(isPeriodAction){
58
+ return <PeriodActionComponent
59
+ {...rest}
60
+ left = {left}
61
+ defaultValue = {defaultValue}
62
+ right = {right}
63
+ />
64
+ }
50
65
  inputMode = defaultStr(inputMode,"start");
51
66
  locale = defaultStr(locale,defaultLocale);
52
67
  const theme = useTheme()
@@ -108,7 +123,6 @@ const DatePickerInput = React.forwardRef(({
108
123
  anchorProps = defaultObj(anchorProps);
109
124
  label = defaultStr(label,text);
110
125
  customRight = React.isValidElement(customRight) || typeof customRight =='function'? customRight : null;
111
- let right = customRight,left = customLeft, isIconLeft = calendarIconBefore;
112
126
  if(withModal){
113
127
  const customLOrR = isIconLeft ? customLeft : customRight;
114
128
  const leftOrRight = (props)=>{
@@ -160,7 +174,7 @@ const DatePickerInput = React.forwardRef(({
160
174
  affix = {false}
161
175
  {...rest}
162
176
  style = {[styles.input,style]}
163
- editable = {editable}
177
+ editable = {isEditable}
164
178
  disabled = {disabled}
165
179
  left = {left}
166
180
  right = {right}
@@ -2,7 +2,7 @@
2
2
  // Use of this source code is governed by a BSD-style
3
3
  // license that can be found in the LICENSE file.
4
4
 
5
- import Date from "./DatePickerInput";
5
+ import DateComponent from "./DatePickerInput";
6
6
  import Time,{parseTime} from "./Time";
7
7
  import React from "$react";
8
8
  import PropTypes from "prop-types";
@@ -10,8 +10,22 @@ import {defaultObj,isNumber,defaultNumber,defaultStr,defaultBool,isNonNullString
10
10
  import theme,{flattenStyle} from "$theme";
11
11
  import DateLib from "$date";
12
12
  import { toDateObj } from "./utils";
13
+ import TextField from "$components/TextField";
14
+ import PeriodActionComponent from "./PeriodAction";
13
15
 
14
- export default function DateTimePickerComponent({left,withSeconds,right,format,dateFormat,timeFormat,defaultValue,onChange,testID,dateProps,disabled,readOnly,timeProps,...rest}){
16
+ export default function DateTimePickerComponent({left,isPeriodAction,withSeconds,right,format,dateFormat,timeFormat,defaultValue,onChange,testID,dateProps,disabled,readOnly,timeProps,...rest}){
17
+ if(!isPeriodAction){
18
+ isPeriodAction = isNonNullString(defaultValue) && defaultValue.contains("=>");
19
+ }
20
+ if(isPeriodAction){
21
+ return <PeriodActionComponent
22
+ {...rest}
23
+ isDateTime
24
+ left = {left}
25
+ defaultValue = {defaultValue}
26
+ right = {right}
27
+ />
28
+ }
15
29
  dateProps = defaultObj(dateProps);
16
30
  timeProps = defaultObj(timeProps);
17
31
  testID = defaultStr(testID,"RN_DateTimeComponent")
@@ -57,7 +71,7 @@ export default function DateTimePickerComponent({left,withSeconds,right,format,d
57
71
  onChange(args);
58
72
  }
59
73
  }
60
- return <Date
74
+ return <DateComponent
61
75
  defaultValue = {dateObj}
62
76
  disabled = {disabled}
63
77
  readOnly = {readOnly}
@@ -107,7 +121,7 @@ export default function DateTimePickerComponent({left,withSeconds,right,format,d
107
121
  }
108
122
 
109
123
  DateTimePickerComponent.propTypes = {
110
- ...Date.propTypes,
124
+ ...DateComponent.propTypes,
111
125
  dateProps : PropTypes.object,
112
126
  timeProps : PropTypes.object,
113
127
  dateFormat : PropTypes.string, //Le format de date
@@ -0,0 +1,31 @@
1
+ // Copyright 2022 @fto-consult/Boris Fouomene. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style
3
+ // license that can be found in the LICENSE file.
4
+ import React from "$react";
5
+ import TextField from "$components/TextField";
6
+ import {isNonNullString} from "$utils";
7
+ import DateLib from "$date";
8
+
9
+ const PeriodActionComponent = React.forwardRef(({defaultValue,label,isDateTime,...props},ref)=>{
10
+ if(isNonNullString(label)){
11
+ label+=" [Période1]";
12
+ }
13
+ const datePeriod= DateLib.formatPeriod(defaultValue,isDateTime);
14
+ if(datePeriod){
15
+ defaultValue = datePeriod;
16
+ }
17
+ return <TextField
18
+ {...props}
19
+ label = {label}
20
+ onChange = {undefined}
21
+ ref = {ref}
22
+ defaultValue = {defaultValue}
23
+ />
24
+ });
25
+
26
+ PeriodActionComponent.displayName = "PeriodActionComponent";
27
+ PeriodActionComponent.propTypes = {
28
+ ...TextField.propTypes
29
+ }
30
+
31
+ export default PeriodActionComponent;
@@ -4,7 +4,7 @@ import DateLib from "$lib/date";
4
4
  import {isNonNullString,defaultStr,isNullOrEmpty,debounce,uniqid} from "$utils";
5
5
  import {regexParser,regexActions,getFilterStateValues} from "./utils";
6
6
  import {parseDecimal} from "$ecomponents/TextField";
7
- import FormDialog from "$ecomponents/Form/FormData/Dialog";
7
+ import notify from "$notify";
8
8
  import PropTypes from "prop-types";
9
9
  import {extendObj} from "$utils";
10
10
  import {getFilterComponentProps} from "$ecomponents/Form/FormData/componentsTypes"
@@ -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 { getSessionData,setSessionData } from "./session";
19
+ import DialogProvider from "$components/Form/FormData/DialogProvider";
19
20
 
20
21
  const manualRunKey = "manual-run";
21
22
 
@@ -39,6 +40,14 @@ const _operators = {
39
40
  '$and' : 'Et', //Array Matches if all the selectors in the array match.
40
41
  '$or' : 'Ou', //Array Matches if any of the selectors in the array match. All selectors must use the same index.
41
42
  }
43
+
44
+ const periodActions = {
45
+ $today:"Aujourd'hui",
46
+ $prevWeek:"Semaine passée",
47
+ $week:'Cette semaine',
48
+ $month:'Ce mois',
49
+ $period:"Période"
50
+ }
42
51
 
43
52
  /***** Coposant Filter, pour les filtres de données */
44
53
  export default class Filter extends AppComponent {
@@ -154,7 +163,7 @@ export default class Filter extends AppComponent {
154
163
  actions = _inActions;
155
164
  defaultAct = "$in";
156
165
  } else if(type == 'date' || type =='datetime') {
157
- actions = {$today:"Aujourd'hui",$prevWeek:"Semaine passée",$week:'Cette semaine',$month:'Ce mois',$period:"Période", ...actions}
166
+ actions = {...periodActions, ...actions}
158
167
  } else if(type !== 'date2time' && type !== 'time' && type !== 'number' && type !== 'decimal'){
159
168
  actions = regexActions;
160
169
  defaultAct = '$regexcontains';
@@ -169,7 +178,7 @@ export default class Filter extends AppComponent {
169
178
  fireValueChanged (forceRun){
170
179
  if(this.willRunManually() && !forceRun) return;
171
180
  let {defaultValue:value,prevDefaultValue,action,ignoreCase,operator} = this.state;
172
- const force = forceRun ===true ? true : false;
181
+ let force = forceRun ===true ? true : false;
173
182
  if(!isObjOrArray(value) && (isNullOrEmpty(value,true) || value ==='undefined') ){
174
183
  value = undefined;
175
184
  }
@@ -240,67 +249,81 @@ export default class Filter extends AppComponent {
240
249
  }
241
250
  })
242
251
  }
252
+ isDateTime(){
253
+ const t = defaultStr(this.type,this.props.type);
254
+ return t.contains("date") && t.contains("time");
255
+ }
243
256
  showPeriodSelector (success){
244
- let split = defaultStr(this.props.defaultValue).split("=>");
245
- let start = new Date().toFormat("yyyy-mm-dd"),
246
- end = start;
247
- if(DateLib.isValidSQLDate(split[0])){
257
+ const defaultValue = defaultStr(this.state.defaultValue).trim();
258
+ let split = defaultValue.split("=>");
259
+ let isDateTime = this.isDateTime();
260
+ let start = isDateTime ? new Date().toSQLDateTimeFormat() : new Date().toSQLDateFormat(), end = start;
261
+
262
+ if(DateLib.isValidSQLDateTime(split[0]) || DateLib.isValidSQLDate(split[0])){
248
263
  start = split[0];
249
264
  }
250
- if(DateLib.isValidSQLDate(split[1])){
265
+ if(DateLib.isValidSQLDateTime(split[1]) || DateLib.isValidSQLDate(split[1])){
251
266
  end = split[1];
252
267
  }
253
- let fContext = undefined;
254
- mountDialog(<FormDialog
255
- visible
256
- key = {_uniqid("period-filter-date")}
257
- fields = {{
258
- start : {type:'date',text:'Du',defaultValue:start},
259
- end : {type:'date',text:'Au',defaultValue:end}
260
- }}
261
- title = {"Définir une période ["+defaultStr(this.props.label,this.props.text)+"]"}
262
- no = {{
263
- text : 'Annuler',
264
- icon : 'cancel'
265
- }}
266
- yes = {{
267
- text : 'Définir',
268
- icon : "check"
269
- }}
270
- onSuccess = {({data})=>{
268
+ const type = isDateTime? "datetime" : "date";
269
+ DialogProvider.open({
270
+ subtitle : false,
271
+ fields : {
272
+ start : {type,text:'Du',defaultValue:start},
273
+ end : {type,text:'Au',defaultValue:end}
274
+ },
275
+ title :"Définir une période ["+defaultStr(this.props.label,this.props.text)+"]",
276
+ cancelButton : true,
277
+ actions : {
278
+ yes : {
279
+ text : 'Définir',
280
+ icon : "check"
281
+ },
282
+ },
283
+ onSuccess : ({data})=>{
284
+ if(data.start && data.end && data.start> data.end){
285
+ return notify.error("La date de fin doit être supérieure à la date de début");
286
+ }
287
+ console.log(data," is dataa")
271
288
  if(isFunction(success)){
272
289
  success(data.start+"=>"+data.end);
273
290
  }
291
+ DialogProvider.close();
274
292
  return true;
275
- }}
276
- />)
293
+ }})
277
294
  }
278
295
  setAction(action,text){
279
296
  if(!(this.searchFilter.current)) return;
280
297
  if(action === this.state.action && action !="$period" && action !== "$today") return;
281
298
  let value = this.state.defaultValue;
282
299
  let act = defaultStr(action).toLowerCase();
300
+ const isDateTime = this.type?.contains("time");
301
+ const dateFormat = isDateTime?DateLib.SQLDateTimeFormat:DateLib.SQLDateFormat;
283
302
  if(action == '$period'){
284
303
  this.showPeriodSelector((d)=>{
285
304
  this.runAction({value:d,action});
286
305
  })
287
306
  } else if(action =="$today"){
288
- return this.runAction({value:new Date().toSQL(),action})
307
+ return this.runAction({value:new Date().resetHours().resetMinutes().resetSeconds().toFormat(dateFormat),action})
289
308
  } else if(act.startsWith("$") && (act.contains("week") || act.contains("month"))){
290
309
  let diff = undefined;
310
+ const currentDate = new Date();
311
+ currentDate.setHours(0);
312
+ currentDate.setMinutes(0);
313
+ currentDate.setSeconds(0);
291
314
  switch (action){
292
315
  case "$month":
293
- diff = DateLib.currentMonthDaysLimits();
316
+ diff = DateLib.currentMonthDaysLimits(currentDate);
294
317
  break;
295
318
  case "$week":
296
- diff = DateLib.currentWeekDaysLimits()
319
+ diff = DateLib.currentWeekDaysLimits(currentDate)
297
320
  break;
298
321
  case "$prevWeek":
299
- diff = DateLib.previousWeekDaysLimits()
322
+ diff = DateLib.previousWeekDaysLimits(currentDate)
300
323
  break;
301
324
  }
302
325
  if(diff){
303
- let value = diff.first.toFormat(DateLib.SQLDateFormat) +"=>"+diff.last.toFormat(DateLib.SQLDateFormat);
326
+ let value = diff.first.toFormat(dateFormat) +"=>"+diff.last.toFormat(dateFormat);
304
327
  this.runAction({value,action})
305
328
  }
306
329
  } else {
@@ -423,6 +446,8 @@ export default class Filter extends AppComponent {
423
446
  if(isFunction(filter)){
424
447
  rest.filter = filter;
425
448
  }
449
+ const isPeriodAction = this.state.actions && periodActions[this.state.action]
450
+ const ignoreDefaultValue = isPeriodAction && isNonNullString(defaultValue) && defaultValue.contains("=>");
426
451
  rest.defaultValue = defaultValue;
427
452
  rest.disabled = rest.readOnly = rest.affix = false;
428
453
  rest.editable = true;
@@ -486,9 +511,14 @@ export default class Filter extends AppComponent {
486
511
 
487
512
  } else if((action =="$period" || (act.startsWith("$") && (act.contains("week") || act.contains("month"))))){
488
513
  let sp = defaultValue.split("=>");
489
- if(DateLib.isValidSQLDate(sp[0]) && DateLib.isValidSQLDate(sp[1])){
490
- x = "Du "+defaultStr(DateLib.format(sp[0],DateLib.defaultDateFormat),sp[0])+" au "+defaultStr(DateLib.format(sp[1],DateLib.defaultDateFormat),sp[1]);
491
- hasS = true;
514
+ x = DateLib.formatDatePeriod(defaultValue,this.isDateTime());
515
+ if(!x){
516
+ if((DateLib.isValidSQLDate(sp[0])|| DateLib.isValidSQLDateTime(sp[0])) && (DateLib.isValidSQLDate(sp[1]) || DateLib.isValidSQLDateTime(sp[1]))){
517
+ x = "Du "+defaultStr(DateLib.format(sp[0],DateLib.defaultDateFormat),sp[0])+" au "+defaultStr(DateLib.format(sp[1],DateLib.defaultDateFormat),sp[1]);
518
+ hasS = true;
519
+ }
520
+ } else {
521
+ hasS = true;
492
522
  }
493
523
  }
494
524
 
@@ -512,10 +542,15 @@ export default class Filter extends AppComponent {
512
542
  const Component = this.Component;
513
543
  const responsiveProps = Object.assign({},responsiveProps);
514
544
  responsiveProps.style = [theme.styles.w100,responsiveProps.style]
545
+ if(ignoreDefaultValue) {
546
+ rest.isPeriodAction = true;
547
+ }
515
548
  return <View testID={testID+"_FilterContainer"} {...containerProps} style={[theme.styles.w100,containerProps.style]}>
516
549
  <Component
517
550
  {...rest}
551
+ readOnly = {ignoreDefaultValue}
518
552
  responsiveProps = {responsiveProps}
553
+ isFilter
519
554
  name = {this.name}
520
555
  testID = {testID}
521
556
  ref = {React.mergeRefs(this.searchFilter,ref)}