@fto-consult/expo-ui 2.2.4 → 2.3.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.
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.4",
3
+ "version": "2.3.1",
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.5",
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",
@@ -11,7 +11,7 @@ import TextField from "$ecomponents/TextField";
11
11
  import Icon from "$ecomponents/Icon";
12
12
  import {StyleSheet,View} from "react-native";
13
13
  import DatePickerModal from '../DatePickerModal'
14
- import "../i18n";
14
+ import PeriodActionComponent from "../PeriodAction";
15
15
 
16
16
  const validMinDate = (date,minDate)=>{
17
17
  if(!minDate || !date) return true;
@@ -44,9 +44,23 @@ const DatePickerInput = React.forwardRef(({
44
44
  style,
45
45
  anchorProps,
46
46
  render_filter,
47
+ isPeriodAction,
48
+ isFilter,
47
49
  calendarIconBefore = false, //si l'icone calendar sera en position left où non
48
50
  ...rest
49
51
  },ref)=>{
52
+ let right = customRight,left = customLeft, isIconLeft = calendarIconBefore;
53
+ if(!isPeriodAction){
54
+ isPeriodAction = isNonNullString(defaultValue) && defaultValue.contains("=>");
55
+ }
56
+ if(isPeriodAction){
57
+ return <PeriodActionComponent
58
+ {...rest}
59
+ left = {left}
60
+ defaultValue = {defaultValue}
61
+ right = {right}
62
+ />
63
+ }
50
64
  inputMode = defaultStr(inputMode,"start");
51
65
  locale = defaultStr(locale,defaultLocale);
52
66
  const theme = useTheme()
@@ -108,7 +122,6 @@ const DatePickerInput = React.forwardRef(({
108
122
  anchorProps = defaultObj(anchorProps);
109
123
  label = defaultStr(label,text);
110
124
  customRight = React.isValidElement(customRight) || typeof customRight =='function'? customRight : null;
111
- let right = customRight,left = customLeft, isIconLeft = calendarIconBefore;
112
125
  if(withModal){
113
126
  const customLOrR = isIconLeft ? customLeft : customRight;
114
127
  const leftOrRight = (props)=>{
@@ -160,7 +173,7 @@ const DatePickerInput = React.forwardRef(({
160
173
  affix = {false}
161
174
  {...rest}
162
175
  style = {[styles.input,style]}
163
- editable = {editable}
176
+ editable = {isEditable}
164
177
  disabled = {disabled}
165
178
  left = {left}
166
179
  right = {right}
@@ -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")
@@ -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;
@@ -9,6 +9,12 @@ const Dictionary = {
9
9
  mustBeLowerThan: 'doit être plus récente de',
10
10
  mustBeBetween: 'doit être entre',
11
11
  dateIsDisabled: 'la date n\'est pas autorisée',
12
+ previous: 'Précédent',
13
+ next: 'Suivant',
14
+ typeInDate: 'Entrer la date',
15
+ pickDateFromCalendar: 'Sélectionner une date dans le calendrier',
16
+ close: 'Fermer',
17
+ "DD/MM/YYYY" : "JJ/MM/AAAA",
12
18
  },
13
19
  en : {
14
20
  save: 'Save',
@@ -20,6 +26,12 @@ const Dictionary = {
20
26
  mustBeLowerThan: 'Must be earlier then',
21
27
  mustBeBetween: 'Must be between',
22
28
  dateIsDisabled: 'Day is not allowed',
29
+ previous: 'Previous',
30
+ next: 'Next',
31
+ typeInDate: 'Type in date',
32
+ pickDateFromCalendar: 'Pick date from calendar',
33
+ close: 'Close',
34
+ "DD/MM/YYYY" : "DD/MM/AAAA"
23
35
  }
24
36
  }
25
37
 
@@ -1,3 +1,4 @@
1
1
  import {registerTranslation} from 'react-native-paper-dates'
2
2
  import Dictionary from "./dictionary";
3
- registerTranslation("fr",Dictionary.fr);
3
+ registerTranslation("fr",Dictionary.fr);
4
+ registerTranslation("en",Dictionary.en);
@@ -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"
@@ -40,6 +40,15 @@ const _operators = {
40
40
  '$and' : 'Et', //Array Matches if all the selectors in the array match.
41
41
  '$or' : 'Ou', //Array Matches if any of the selectors in the array match. All selectors must use the same index.
42
42
  }
43
+
44
+ const periodActions = {
45
+ $yesterday : "Hier",
46
+ $today:"Aujourd'hui",
47
+ $prevWeek:"Semaine passée",
48
+ $week:'Cette semaine',
49
+ $month:'Ce mois',
50
+ $period:"Période"
51
+ }
43
52
 
44
53
  /***** Coposant Filter, pour les filtres de données */
45
54
  export default class Filter extends AppComponent {
@@ -155,7 +164,7 @@ export default class Filter extends AppComponent {
155
164
  actions = _inActions;
156
165
  defaultAct = "$in";
157
166
  } else if(type == 'date' || type =='datetime') {
158
- actions = {$today:"Aujourd'hui",$prevWeek:"Semaine passée",$week:'Cette semaine',$month:'Ce mois',$period:"Période", ...actions}
167
+ actions = {...periodActions, ...actions}
159
168
  } else if(type !== 'date2time' && type !== 'time' && type !== 'number' && type !== 'decimal'){
160
169
  actions = regexActions;
161
170
  defaultAct = '$regexcontains';
@@ -177,7 +186,7 @@ export default class Filter extends AppComponent {
177
186
  let originValue = value;
178
187
  const type = defaultStr(this.props.type).toLowerCase().trim();
179
188
  value = parseDecimal(value,type);
180
- if(action =="$today"){
189
+ if(action =="$today" || action =='$yesterday'){
181
190
  force = true;
182
191
  }
183
192
  let prev = JSON.stringify(defaultObj(this.previousObj)),//{value:this.previousValue,operator:this.previousOperator,action:this.previousAction}
@@ -198,7 +207,7 @@ export default class Filter extends AppComponent {
198
207
  let originAction = action;
199
208
  if(isNonNullString(action)){
200
209
  action = action.toLowerCase().trim();
201
- if(action =="$today"){
210
+ if(action =="$today" || action =='$yesterday'){
202
211
  action = "$eq";
203
212
  } else if(action.startsWith("$") && (action.contains("week") || action.contains("month"))){
204
213
  action = "$period";
@@ -241,38 +250,41 @@ export default class Filter extends AppComponent {
241
250
  }
242
251
  })
243
252
  }
253
+ isDateTime(){
254
+ const t = defaultStr(this.type,this.props.type);
255
+ return t.contains("date") && t.contains("time");
256
+ }
244
257
  showPeriodSelector (success){
245
- let split = defaultStr(this.props.defaultValue).split("=>");
246
- let start = new Date().toFormat("yyyy-mm-dd"),
247
- end = start;
248
- if(DateLib.isValidSQLDate(split[0])){
258
+ const defaultValue = defaultStr(this.state.defaultValue).trim();
259
+ let split = defaultValue.split("=>");
260
+ let isDateTime = this.isDateTime();
261
+ let start = isDateTime ? new Date().toSQLDateTimeFormat() : new Date().toSQLDateFormat(), end = start;
262
+
263
+ if(DateLib.isValidSQLDateTime(split[0]) || DateLib.isValidSQLDate(split[0])){
249
264
  start = split[0];
250
265
  }
251
- if(DateLib.isValidSQLDate(split[1])){
266
+ if(DateLib.isValidSQLDateTime(split[1]) || DateLib.isValidSQLDate(split[1])){
252
267
  end = split[1];
253
268
  }
254
- const type = this.type.contains("date")? this.type : "date";
269
+ const type = isDateTime? "datetime" : "date";
255
270
  DialogProvider.open({
271
+ subtitle : false,
256
272
  fields : {
257
273
  start : {type,text:'Du',defaultValue:start},
258
274
  end : {type,text:'Au',defaultValue:end}
259
275
  },
260
276
  title :"Définir une période ["+defaultStr(this.props.label,this.props.text)+"]",
277
+ cancelButton : true,
261
278
  actions : {
262
- no : {
263
- text : 'Annuler',
264
- icon : 'cancel',
265
- isFormAction : false,
266
- onPress : ()=>{
267
- DialogProvider.close();
268
- }
269
- },
270
279
  yes : {
271
280
  text : 'Définir',
272
281
  icon : "check"
273
282
  },
274
283
  },
275
284
  onSuccess : ({data})=>{
285
+ if(data.start && data.end && data.start> data.end){
286
+ return notify.error("La date de fin doit être supérieure à la date de début");
287
+ }
276
288
  console.log(data," is dataa")
277
289
  if(isFunction(success)){
278
290
  success(data.start+"=>"+data.end);
@@ -283,7 +295,7 @@ export default class Filter extends AppComponent {
283
295
  }
284
296
  setAction(action,text){
285
297
  if(!(this.searchFilter.current)) return;
286
- if(action === this.state.action && action !="$period" && action !== "$today") return;
298
+ if(action === this.state.action && action !="$period" && action !== "$today" && action !='$yesterday') return;
287
299
  let value = this.state.defaultValue;
288
300
  let act = defaultStr(action).toLowerCase();
289
301
  const isDateTime = this.type?.contains("time");
@@ -293,8 +305,10 @@ export default class Filter extends AppComponent {
293
305
  this.runAction({value:d,action});
294
306
  })
295
307
  } else if(action =="$today"){
296
- return this.runAction({value:new Date().toDateFormat(dateFormat),action})
297
- } else if(act.startsWith("$") && (act.contains("week") || act.contains("month"))){
308
+ return this.runAction({value:new Date().resetHours().resetMinutes().resetSeconds().toFormat(dateFormat),action})
309
+ } else if(action =="$yesterday"){
310
+ return this.runAction({value: DateLib.removeDays(1,new Date(),null,true).resetHours().resetMinutes().resetSeconds().toFormat(dateFormat),action})
311
+ } else if(act.startsWith("$") && (act.contains("week") || act.contains("month"))){
298
312
  let diff = undefined;
299
313
  const currentDate = new Date();
300
314
  currentDate.setHours(0);
@@ -435,6 +449,8 @@ export default class Filter extends AppComponent {
435
449
  if(isFunction(filter)){
436
450
  rest.filter = filter;
437
451
  }
452
+ const isPeriodAction = this.state.actions && periodActions[this.state.action]
453
+ const ignoreDefaultValue = isPeriodAction && isNonNullString(defaultValue) && defaultValue.contains("=>");
438
454
  rest.defaultValue = defaultValue;
439
455
  rest.disabled = rest.readOnly = rest.affix = false;
440
456
  rest.editable = true;
@@ -494,13 +510,18 @@ export default class Filter extends AppComponent {
494
510
  if(checked && (isNumber(defaultValue) || isNonNullString(defaultValue))) {
495
511
  let hasS = false;
496
512
  let act = defaultStr(action).toLowerCase();
497
- if(act =="$today"){
513
+ if(act =="$today" || act =='$yesterday'){
498
514
 
499
515
  } else if((action =="$period" || (act.startsWith("$") && (act.contains("week") || act.contains("month"))))){
500
516
  let sp = defaultValue.split("=>");
501
- if(DateLib.isValidSQLDate(sp[0]) && DateLib.isValidSQLDate(sp[1])){
502
- x = "Du "+defaultStr(DateLib.format(sp[0],DateLib.defaultDateFormat),sp[0])+" au "+defaultStr(DateLib.format(sp[1],DateLib.defaultDateFormat),sp[1]);
503
- hasS = true;
517
+ x = DateLib.formatDatePeriod(defaultValue,this.isDateTime());
518
+ if(!x){
519
+ if((DateLib.isValidSQLDate(sp[0])|| DateLib.isValidSQLDateTime(sp[0])) && (DateLib.isValidSQLDate(sp[1]) || DateLib.isValidSQLDateTime(sp[1]))){
520
+ x = "Du "+defaultStr(DateLib.format(sp[0],DateLib.defaultDateFormat),sp[0])+" au "+defaultStr(DateLib.format(sp[1],DateLib.defaultDateFormat),sp[1]);
521
+ hasS = true;
522
+ }
523
+ } else {
524
+ hasS = true;
504
525
  }
505
526
  }
506
527
 
@@ -524,10 +545,15 @@ export default class Filter extends AppComponent {
524
545
  const Component = this.Component;
525
546
  const responsiveProps = Object.assign({},responsiveProps);
526
547
  responsiveProps.style = [theme.styles.w100,responsiveProps.style]
548
+ if(ignoreDefaultValue) {
549
+ rest.isPeriodAction = true;
550
+ }
527
551
  return <View testID={testID+"_FilterContainer"} {...containerProps} style={[theme.styles.w100,containerProps.style]}>
528
552
  <Component
529
553
  {...rest}
554
+ readOnly = {ignoreDefaultValue}
530
555
  responsiveProps = {responsiveProps}
556
+ isFilter
531
557
  name = {this.name}
532
558
  testID = {testID}
533
559
  ref = {React.mergeRefs(this.searchFilter,ref)}
@@ -1,11 +0,0 @@
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
-
5
- import i18n from "$i18n";
6
-
7
- i18n.dictionary({
8
- fr : {
9
- "DD/MM/YYYY" : "JJ/MM/AAAA"
10
- }
11
- })