@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 +15 -3
- package/package.json +2 -2
- package/src/components/Date/DatePickerInput/index.js +16 -3
- package/src/components/Date/DateTime.js +15 -1
- package/src/components/Date/PeriodAction.js +31 -0
- package/src/components/Date/dictionary.js +12 -0
- package/src/components/Date/utils.common.js +2 -1
- package/src/components/Filter/index.js +51 -25
- package/src/components/Date/i18n.js +0 -11
package/index.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import { registerRootComponent } from
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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 "../
|
|
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 = {
|
|
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
|
|
|
@@ -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
|
|
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 = {
|
|
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
|
-
|
|
246
|
-
let
|
|
247
|
-
|
|
248
|
-
|
|
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 =
|
|
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().
|
|
297
|
-
} else if(
|
|
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
|
-
|
|
502
|
-
|
|
503
|
-
|
|
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
|
-
})
|