@fto-consult/expo-ui 2.19.8 → 2.20.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 +2 -2
- package/src/components/Datagrid/Common/Common.js +57 -12
- package/src/components/Date/FormatSelector.js +98 -0
- package/src/components/Date/index.js +3 -0
- package/src/components/Form/Fields/SelectCountry.js +3 -1
- package/src/components/Form/Fields/SelectDateFormat.js +46 -0
- package/src/components/Form/Fields/index.js +3 -0
- package/src/components/Form/FormData/FormData.js +2 -2
- package/src/components/Form/FormData/componentsTypes.js +9 -2
- package/src/components/Snackbar/index.js +3 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fto-consult/expo-ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.20.0",
|
|
4
4
|
"description": "Bibliothèque de composants UI Expo,react-native",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"@emotion/native": "^11.10.0",
|
|
62
62
|
"@expo/html-elements": "^0.2.0",
|
|
63
63
|
"@expo/vector-icons": "^13.0.0",
|
|
64
|
-
"@fto-consult/common": "^1.
|
|
64
|
+
"@fto-consult/common": "^1.23.2",
|
|
65
65
|
"@gorhom/portal": "^1.0.14",
|
|
66
66
|
"@react-native-async-storage/async-storage": "~1.17.3",
|
|
67
67
|
"@react-native-community/datetimepicker": "6.5.2",
|
|
@@ -37,6 +37,7 @@ import {Flag} from "$ecomponents/Countries"
|
|
|
37
37
|
import View from "$ecomponents/View";
|
|
38
38
|
import {Menu} from "$ecomponents/BottomSheet";
|
|
39
39
|
import {styles as tableStyles} from "$ecomponents/Table";
|
|
40
|
+
import {DialogProvider} from "$ecomponents/Form/FormData";
|
|
40
41
|
|
|
41
42
|
export const arrayValueSeparator = ", ";
|
|
42
43
|
|
|
@@ -993,6 +994,44 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
993
994
|
}
|
|
994
995
|
return null;
|
|
995
996
|
}
|
|
997
|
+
/*** configure la */
|
|
998
|
+
configureSectionListColumn(column){
|
|
999
|
+
if(!isObj(column) || !isNonNullString(column.field) || !isObj(this.state.columns[column.field])){
|
|
1000
|
+
return Promise.reject({message : 'type de colonne invalide, impossible de configurer la colonne, pour permettre qu\elle soit ajoutée dans les colonnes de groupe du tableau'})
|
|
1001
|
+
}
|
|
1002
|
+
const col = this.state.columns[column.field];
|
|
1003
|
+
const type = defaultStr(col.jsType,col.type).toLowerCase();
|
|
1004
|
+
if(type.contains("date") || type =='time'){
|
|
1005
|
+
return new Promise((resolve,reject)=>{
|
|
1006
|
+
DialogProvider.open({
|
|
1007
|
+
fields : {
|
|
1008
|
+
dateFormat : {
|
|
1009
|
+
type : 'select_dateformat',
|
|
1010
|
+
required : true,
|
|
1011
|
+
text : 'Sélectionnez un format de date',
|
|
1012
|
+
defaultValue : "dd/mm/yyyy",
|
|
1013
|
+
}
|
|
1014
|
+
},
|
|
1015
|
+
onCancelButtonPress : ()=>{
|
|
1016
|
+
DialogProvider.close();
|
|
1017
|
+
reject({msg:'aucun format sélectionné'})
|
|
1018
|
+
},
|
|
1019
|
+
actions : [{
|
|
1020
|
+
text : "Sélectionnez",
|
|
1021
|
+
icon : "check",
|
|
1022
|
+
onPress : ({data})=>{
|
|
1023
|
+
column.format = data.dateFormat;
|
|
1024
|
+
DialogProvider.close();
|
|
1025
|
+
setTimeout(()=>{
|
|
1026
|
+
resolve(column);
|
|
1027
|
+
},100)
|
|
1028
|
+
},
|
|
1029
|
+
}]
|
|
1030
|
+
})
|
|
1031
|
+
})
|
|
1032
|
+
}
|
|
1033
|
+
return Promise.resolve(column);
|
|
1034
|
+
}
|
|
996
1035
|
toggleColumnInSectionList(columnName){
|
|
997
1036
|
if(!isNonNullString(columnName) || !isObj(this.state.columns[columnName])) return;
|
|
998
1037
|
if(!isObj(this.state.sectionListColumns) || !Array.isArray(this.preparedColumns?.sectionListColumnsMenuItems))return;
|
|
@@ -1002,16 +1041,24 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1002
1041
|
if(isObj(sectionListColumns[columnName])){
|
|
1003
1042
|
delete sectionListColumns[columnName];
|
|
1004
1043
|
} else {
|
|
1005
|
-
sectionListColumns[columnName] = {};
|
|
1006
|
-
}
|
|
1007
|
-
const
|
|
1008
|
-
|
|
1009
|
-
this.
|
|
1010
|
-
this.
|
|
1011
|
-
this.
|
|
1044
|
+
sectionListColumns[columnName] = {field:columnName};
|
|
1045
|
+
}
|
|
1046
|
+
const cb =()=>{
|
|
1047
|
+
const {sectionListColumns:pSListColumns} = this.prepareColumns({sectionListColumns});
|
|
1048
|
+
this.setIsLoading(true,()=>{
|
|
1049
|
+
this.prepareData({data:this.INITIAL_STATE.data,sectionListColumns:pSListColumns},(state)=>{
|
|
1050
|
+
this.setState({...state,sectionListColumns:pSListColumns},()=>{
|
|
1051
|
+
this.setIsLoading(false,false);
|
|
1052
|
+
});
|
|
1012
1053
|
});
|
|
1013
|
-
});
|
|
1014
|
-
}
|
|
1054
|
+
},true);
|
|
1055
|
+
}
|
|
1056
|
+
setTimeout(() => {
|
|
1057
|
+
if(!isObj(sectionListColumns[columnName])){
|
|
1058
|
+
return cb();
|
|
1059
|
+
}
|
|
1060
|
+
return this.configureSectionListColumn(sectionListColumns[columnName]).then(cb).catch(notify.error)
|
|
1061
|
+
}, 200);
|
|
1015
1062
|
}
|
|
1016
1063
|
removeAllColumnsInSectionList(){
|
|
1017
1064
|
const {sectionListColumns} = this.prepareColumns({sectionListColumns:{}});
|
|
@@ -1230,9 +1277,7 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1230
1277
|
sectionListColumnsMenuItems.push({
|
|
1231
1278
|
field,
|
|
1232
1279
|
onPress : ()=>{
|
|
1233
|
-
|
|
1234
|
-
this.toggleColumnInSectionList(field);
|
|
1235
|
-
},300)
|
|
1280
|
+
this.toggleColumnInSectionList(field);
|
|
1236
1281
|
return false;
|
|
1237
1282
|
},
|
|
1238
1283
|
title : title,
|
|
@@ -0,0 +1,98 @@
|
|
|
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 DateLib from "$date";
|
|
5
|
+
import React from "$react";
|
|
6
|
+
import {defaultObj,isNonNullString} from "$utils";
|
|
7
|
+
import SimpleSelect from "$ecomponents/SimpleSelect";
|
|
8
|
+
import Provider from "$ecomponents/Dialog/Provider";
|
|
9
|
+
import TextField from "$components/TextField";
|
|
10
|
+
import Label from "$components/Label";
|
|
11
|
+
import theme from "$theme";
|
|
12
|
+
import notify from "$notify";
|
|
13
|
+
import { View } from "react-native";
|
|
14
|
+
import Icon from "$components/Icon";
|
|
15
|
+
import PropTypes from "prop-types";
|
|
16
|
+
|
|
17
|
+
const DateFormatSelector = React.forwardRef((props,ref)=>{
|
|
18
|
+
return <SimpleSelect ref={ref} {...selectDateFormatFieldProps(props)}/>
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
DateFormatSelector.displayName = "DateFormatSelector";
|
|
22
|
+
|
|
23
|
+
export default DateFormatSelector;
|
|
24
|
+
|
|
25
|
+
/*** onAdd est appelé lorsqu'on ajoute un format personalisé */
|
|
26
|
+
export const selectDateFormatFieldProps = ({onAdd:customOnAdd,onAddCustomFormat,...props})=>{
|
|
27
|
+
const onAdd = ()=>{
|
|
28
|
+
const labelRef = React.createRef(null);
|
|
29
|
+
const valueRef = React.createRef(null);
|
|
30
|
+
Provider.open(({
|
|
31
|
+
title : "Ajouter un format de date personalisé",
|
|
32
|
+
children : <View style={[theme.styles.w100,theme.styles.ph1]}>
|
|
33
|
+
<TextField
|
|
34
|
+
type = "text"
|
|
35
|
+
label = "Format personalisé"
|
|
36
|
+
right ={(p)=><Icon {...p} name ="material-help" title="Utilisez les champ d : pour date, m pour mois, y pour année, H pour heure, M pour minute, s pour seconde. les jour sur 3 lettres (Lun) sont : ddd, les jours écris complètement sont ddddd (Lundi); les mois en court sont définis par mmm (Juil), les mois en complet : mmmm (Juillet)."/>}
|
|
37
|
+
onChange = {(args)=>{
|
|
38
|
+
const {value} = args;
|
|
39
|
+
if(!labelRef.current || !labelRef.current.update) return;
|
|
40
|
+
if((value)){
|
|
41
|
+
try {
|
|
42
|
+
var d = new Date().toFormat(value);
|
|
43
|
+
if(d){
|
|
44
|
+
labelRef.current.update(d);
|
|
45
|
+
valueRef.current = {...args,code:value,label:d};
|
|
46
|
+
} else {
|
|
47
|
+
labelRef.current.update("");
|
|
48
|
+
valueRef.current = null;
|
|
49
|
+
}
|
|
50
|
+
} catch{
|
|
51
|
+
labelRef.current.update("");
|
|
52
|
+
valueRef.current = null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}}
|
|
56
|
+
/>
|
|
57
|
+
<View style={[theme.styles.w100,theme.styles.row,theme.styles.flexWrap]}>
|
|
58
|
+
<Label>EX : </Label>
|
|
59
|
+
<Label.withRef primary textBold ref={labelRef}></Label.withRef>
|
|
60
|
+
</View>
|
|
61
|
+
</View>,
|
|
62
|
+
actions : [{
|
|
63
|
+
text : "Valider",
|
|
64
|
+
icon : "check",
|
|
65
|
+
onPress : ()=>{
|
|
66
|
+
if(!isObj(valueRef.current) || !isNonNullString(valueRef.current.value)){
|
|
67
|
+
return notify.error("Vous devez spécifier un format valide");
|
|
68
|
+
}
|
|
69
|
+
if(typeof customOnAdd =='function'){
|
|
70
|
+
customOnAdd(valueRef.current);
|
|
71
|
+
}
|
|
72
|
+
Provider.close();
|
|
73
|
+
}
|
|
74
|
+
}],
|
|
75
|
+
}))
|
|
76
|
+
};
|
|
77
|
+
return {
|
|
78
|
+
items : getDateFormatSelectorItems(),
|
|
79
|
+
getItemValue : ({item})=>item.code,
|
|
80
|
+
renderItem : dateFormatSelectorRenderItem,
|
|
81
|
+
showAdd : true,
|
|
82
|
+
...defaultObj(props),
|
|
83
|
+
onAdd,
|
|
84
|
+
onAdd : undefined,
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export const getDateFormatSelectorItems = x=> Object.map(DateLib.formats,(format)=>{
|
|
88
|
+
return {code : format,label:new Date().toFormat(format)}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
export const dateFormatSelectorRenderItem = ({item})=>{
|
|
92
|
+
return "{0}, EX : {1}".sprintf(item.code,item.label);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
DateFormatSelector.propTypes = {
|
|
96
|
+
...SimpleSelect.propTypes,
|
|
97
|
+
//appelée lorsqu'on ajoute un format personalisé
|
|
98
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import SelectField from "./SelectField";
|
|
2
2
|
import {getCountryFieldProps} from "$ecomponents/Countries";
|
|
3
|
-
import {defaultVal} from "$utils";
|
|
4
3
|
|
|
5
4
|
export default class FormFieldSelectCountry extends SelectField{
|
|
6
5
|
getComponentProps(props){
|
|
@@ -9,4 +8,7 @@ export default class FormFieldSelectCountry extends SelectField{
|
|
|
9
8
|
_render(props){
|
|
10
9
|
return super._render(this.getComponentProps(props))
|
|
11
10
|
}
|
|
11
|
+
}
|
|
12
|
+
FormFieldSelectCountry.propTypes = {
|
|
13
|
+
...SelectField.propTypes,
|
|
12
14
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import SelectField from "./SelectField";
|
|
2
|
+
import {selectDateFormatFieldProps,getDateFormatSelectorItems} from "$ecomponents/Date/FormatSelector";
|
|
3
|
+
import DateLib from "$date";
|
|
4
|
+
|
|
5
|
+
export default class FormFieldSelectDateFormat extends SelectField{
|
|
6
|
+
constructor(props){
|
|
7
|
+
super(props);
|
|
8
|
+
Object.defineProperties(this,{
|
|
9
|
+
itemsRef : {value : {current : getDateFormatSelectorItems()}},
|
|
10
|
+
valueRef : {value : {current : undefined}},
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
getComponentProps(props){
|
|
14
|
+
const {onAdd} = props;
|
|
15
|
+
const rest = selectDateFormatFieldProps({
|
|
16
|
+
...props,onAdd : (args)=>{
|
|
17
|
+
if(onAdd && onAdd(args) === false){
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const {value,label} = args;
|
|
21
|
+
const code = value+"-"+value;
|
|
22
|
+
const it = {[code]:{code : value, label : label || new Date().toFormat(value)}}
|
|
23
|
+
Object.map(this.itemsRef.current,(v,k)=>{
|
|
24
|
+
it[k] = v;
|
|
25
|
+
});
|
|
26
|
+
this.valueRef.current = value;
|
|
27
|
+
if(this._field && this._field.refresh && this._field.prepareItems){
|
|
28
|
+
this._field.setState(this._field.prepareItems({items:it,defaultValue:value}))
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
rest.items = this.itemsRef.current;
|
|
33
|
+
if(this.valueRef.current){
|
|
34
|
+
rest.defaultValue = this.valueRef.current;
|
|
35
|
+
}
|
|
36
|
+
this.valueRef.current = undefined;
|
|
37
|
+
return rest;
|
|
38
|
+
}
|
|
39
|
+
_render(props){
|
|
40
|
+
return super._render(this.getComponentProps(props))
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
FormFieldSelectDateFormat.propTypes = {
|
|
45
|
+
...SelectField.propTypes,
|
|
46
|
+
}
|
|
@@ -18,6 +18,7 @@ import Html from "./Html";
|
|
|
18
18
|
import * as eFormFields from "$extendFormFields";
|
|
19
19
|
import "$utils";
|
|
20
20
|
import React from "$react";
|
|
21
|
+
import SelectDateFormat from "./SelectDateFormat";
|
|
21
22
|
|
|
22
23
|
export * from "$extendFormFields";
|
|
23
24
|
|
|
@@ -38,6 +39,7 @@ const defFormFields = {
|
|
|
38
39
|
,Time
|
|
39
40
|
,Image
|
|
40
41
|
,Tel
|
|
42
|
+
,SelectDateFormat
|
|
41
43
|
,Html
|
|
42
44
|
}
|
|
43
45
|
|
|
@@ -67,5 +69,6 @@ export {
|
|
|
67
69
|
,Time
|
|
68
70
|
,Image
|
|
69
71
|
,Tel
|
|
72
|
+
,SelectDateFormat
|
|
70
73
|
,Html
|
|
71
74
|
}
|
|
@@ -10,7 +10,7 @@ import PropTypes from "prop-types";
|
|
|
10
10
|
import {renderActions} from "$ecomponents/Dialog/utils";
|
|
11
11
|
//import {isDocUpdate} from "$database/utils";
|
|
12
12
|
import {handleBeforeSaveCallback} from "./utils";
|
|
13
|
-
import
|
|
13
|
+
import componentsTypes from "./componentsTypes";
|
|
14
14
|
import { keyboardShortcuts } from "../utils";
|
|
15
15
|
|
|
16
16
|
export default class FormDataComponent extends AppComponent{
|
|
@@ -191,7 +191,7 @@ export default class FormDataComponent extends AppComponent{
|
|
|
191
191
|
} else if(isObj(field) && field.form !== false) {
|
|
192
192
|
const name = defaultStr(field.name,field.field,index);
|
|
193
193
|
const type = defaultStr(field.jsType,field.type,"text").trim().toLowerCase().replaceAll("_","");
|
|
194
|
-
const Component =
|
|
194
|
+
const Component = componentsTypes[type] || componentsTypes.default;
|
|
195
195
|
let {defaultValue,useDefaultValueFromData,hidden,renderFormDataField,getMediaQueryStyle,printLabels,queryLimit,selected,value,visible,dataFilesInterest,perm,ignore,form,responsiveProps:customResponsiveProps,...rest} = field;
|
|
196
196
|
rest = Object.assign({},rest);
|
|
197
197
|
delete rest.import;
|
|
@@ -14,8 +14,9 @@ const componentTypes = {
|
|
|
14
14
|
piece : Fields.PieceField,
|
|
15
15
|
select : Fields.SelectField,
|
|
16
16
|
switch : Fields.Switch,
|
|
17
|
-
select_country : Fields.SelectCountry,
|
|
18
17
|
selectcountry : Fields.SelectCountry,
|
|
18
|
+
selectdateformat : Fields.SelectDateFormat,
|
|
19
|
+
dateformat : Fields.SelectDateFormat,
|
|
19
20
|
date : Fields.Date,
|
|
20
21
|
time : Fields.Time,
|
|
21
22
|
datetime : Fields.DateTime,
|
|
@@ -97,9 +98,15 @@ export const getFilterComponentProps = (_props)=>{
|
|
|
97
98
|
component = type == 'datetime' ? Fields.DateTime : type === 'date'? Fields.Date : Fields.Time;
|
|
98
99
|
} else if(type == 'color' || type =='colorpicker') {
|
|
99
100
|
component = Fields.ColorPicker;
|
|
100
|
-
} else if(
|
|
101
|
+
} else if(type == 'dateformat' || type =='select_dateformat' || type =='select_date_format') {
|
|
102
|
+
component = Fields.SelectDateFormat;
|
|
103
|
+
} else if(React.isComponent()) {
|
|
101
104
|
component = componentTypes[type];
|
|
102
105
|
}else {
|
|
106
|
+
const tt = type.replaceAll("_","").toLowerCase();
|
|
107
|
+
if(React.isComponent(componentTypes[tt])){
|
|
108
|
+
component = componentTypes[tt];
|
|
109
|
+
}
|
|
103
110
|
delete props.dbName;
|
|
104
111
|
delete props.tableName;
|
|
105
112
|
props.label = label;
|
|
@@ -118,6 +118,7 @@ const Snackbar = ({
|
|
|
118
118
|
paddingBottom: bottom,
|
|
119
119
|
paddingHorizontal: Math.max(left, right),
|
|
120
120
|
};
|
|
121
|
+
action = React.isValidElement(action)? action : null;
|
|
121
122
|
return (
|
|
122
123
|
<View
|
|
123
124
|
testID={testID+"_Container"}
|
|
@@ -150,13 +151,13 @@ const Snackbar = ({
|
|
|
150
151
|
style
|
|
151
152
|
]}
|
|
152
153
|
>
|
|
153
|
-
{<View testID={testID+"_Content"} {...contentProps} style={[styles.content,contentProps.style]}>
|
|
154
|
+
{<View testID={testID+"_Content"} {...contentProps} style={[styles.content,contentProps.style,action && theme.styles.pr1]}>
|
|
154
155
|
{typeof children =='string' || typeof children ==='string' ?
|
|
155
156
|
<Label {...labelProps} style={[{color:flattenStyle.color,backgroundColor:flattenStyle.backgroundColor},labelProps.style]}>
|
|
156
157
|
{children}
|
|
157
158
|
</Label> : React.isValidElement(children)? children : null}
|
|
158
159
|
</View>}
|
|
159
|
-
{
|
|
160
|
+
{action}
|
|
160
161
|
</Surface>
|
|
161
162
|
</View>
|
|
162
163
|
);
|