@fto-consult/expo-ui 2.14.2 → 2.15.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/Checkbox.js +3 -1
- package/src/components/Datagrid/SWRDatagrid.js +24 -3
- package/src/components/Datagrid/Table/index.js +2 -1
- package/src/components/Form/Fields/Field.js +1 -1
- package/src/components/Label/index.js +6 -1
- package/src/layouts/Screen/TableData.js +39 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fto-consult/expo-ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.15.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.21.
|
|
64
|
+
"@fto-consult/common": "^1.21.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",
|
|
@@ -2,12 +2,14 @@ import {Checkbox} from "$ecomponents/Icon";
|
|
|
2
2
|
import React from "$react";
|
|
3
3
|
import {defaultObj,isObj} from "$utils";
|
|
4
4
|
import PropTypes from "prop-types";
|
|
5
|
+
import theme from "$theme";
|
|
5
6
|
|
|
6
7
|
const DatagridCheckboxComponent = React.forwardRef((props,ref)=>{
|
|
7
8
|
const {onChange,rowKey,rowData,row,rowIndex,index,rowsRefs,...rest} = props;
|
|
8
9
|
return <Checkbox
|
|
9
10
|
secondaryOnCheck
|
|
10
|
-
{...
|
|
11
|
+
{...rest}
|
|
12
|
+
style = {[rest.style,theme.styles.alignItemsCenter]}
|
|
11
13
|
ref = {(el)=>{
|
|
12
14
|
React.setRef(ref,el);
|
|
13
15
|
if(isObj(rowsRefs) && rowKey){
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @see :
|
|
7
7
|
*/
|
|
8
8
|
import Datagrid from "./IndexComponent";
|
|
9
|
-
import {defaultStr,defaultObj,defaultVal,isObjOrArray,isObj,extendObj} from "$utils";
|
|
9
|
+
import {defaultStr,defaultObj,defaultVal,isNonNullString,defaultNumber,isObjOrArray,isObj,extendObj} from "$utils";
|
|
10
10
|
import {Pressable} from "react-native";
|
|
11
11
|
import SimpleSelect from "$ecomponents/SimpleSelect";
|
|
12
12
|
import React from "$react";
|
|
@@ -27,6 +27,26 @@ import PropTypes from "prop-types";
|
|
|
27
27
|
import {isDesktopMedia} from "$dimensions";
|
|
28
28
|
import ActivityIndicator from "$ecomponents/ActivityIndicator";
|
|
29
29
|
import {Menu} from "$ecomponents/BottomSheet";
|
|
30
|
+
import session from "$session";
|
|
31
|
+
|
|
32
|
+
export const getSessionKey = ()=>{
|
|
33
|
+
return Auth.getSessionKey("swrDatagrid");
|
|
34
|
+
}
|
|
35
|
+
export const getSessionData = (key)=>{
|
|
36
|
+
const data = defaultObj(session.get(getSessionKey()));
|
|
37
|
+
return isNonNullString(key) ? data[key.trim()] : data;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const setSessionData = (key,value)=>{
|
|
41
|
+
const d = getSessionData();
|
|
42
|
+
if(isObj(key)){
|
|
43
|
+
return session.set(getSessionKey(),extendObj({},d,key));
|
|
44
|
+
}
|
|
45
|
+
d[key] = value;
|
|
46
|
+
return session.set(getSessionKey(),d);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
30
50
|
|
|
31
51
|
const timeout = 5000*60*60;
|
|
32
52
|
export const swrOptions = {
|
|
@@ -110,7 +130,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
|
110
130
|
const totalRef = React.useRef(0);
|
|
111
131
|
const isFetchingRef = React.useRef(false);
|
|
112
132
|
const pageRef = React.useRef(1);
|
|
113
|
-
const limitRef = React.useRef(500);
|
|
133
|
+
const limitRef = React.useRef(defaultNumber(getSessionData("limit"),500));
|
|
114
134
|
const isInitializedRef = React.useRef(false);
|
|
115
135
|
testID = defaultStr(testID,"RNSWRDatagridComponent")
|
|
116
136
|
const {error, isValidating,isLoading,refresh} = useSWR(fetchPath,{
|
|
@@ -254,7 +274,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
|
254
274
|
style = {sStyle}
|
|
255
275
|
anchor = {(p)=>{
|
|
256
276
|
return <Pressable style={[theme.styles.noMargin,theme.styles.noPadding]} {...p} testID={testID+"MenuSelectLimit"}>
|
|
257
|
-
<Label primary
|
|
277
|
+
<Label primary testID={testID+"_Label"} fontSize={16}>
|
|
258
278
|
{limitRef.current.formatNumber()}
|
|
259
279
|
</Label>
|
|
260
280
|
</Pressable>
|
|
@@ -268,6 +288,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
|
268
288
|
onPress : ()=>{
|
|
269
289
|
if(item == limitRef.current) return;
|
|
270
290
|
limitRef.current = item;
|
|
291
|
+
setSessionData("limit",limitRef.current);
|
|
271
292
|
pageRef.current = firstPage;
|
|
272
293
|
setTimeout(() => {
|
|
273
294
|
doRefresh(true);
|
|
@@ -677,7 +677,7 @@ export default class Field extends AppComponent {
|
|
|
677
677
|
return true;
|
|
678
678
|
}
|
|
679
679
|
onBlurField(event){
|
|
680
|
-
if(isFunction(this.props.onBlur) && this.props.onBlur({event,context:this}) === false){
|
|
680
|
+
if(isFunction(this.props.onBlur) && this.props.onBlur({event,value:this.getValue(),context:this}) === false){
|
|
681
681
|
return;
|
|
682
682
|
}
|
|
683
683
|
if(this.isFilter()) return
|
|
@@ -10,7 +10,7 @@ const defaultSelectable = canTextBeSelectable();
|
|
|
10
10
|
|
|
11
11
|
export const EllipsizeMode = {'head':'head','middle':'middle', 'tail':'tail' , 'clip':'clip'}
|
|
12
12
|
|
|
13
|
-
const LabelComponent = React.forwardRef(({ children,upperCase,testID,wrap,nativeID,wrapText,error,underlined,splitText,secondary,primary,bold,textBold,disabled,text,style,...rest},ref)=> {
|
|
13
|
+
const LabelComponent = React.forwardRef(({ children,upperCase,fontSize,testID,wrap,nativeID,wrapText,error,underlined,splitText,secondary,primary,bold,textBold,disabled,text,style,...rest},ref)=> {
|
|
14
14
|
children = defaultVal(children,text);
|
|
15
15
|
let isText = false;
|
|
16
16
|
if(!React.isValidElement(children) && Array.isArray(children) && children.length){
|
|
@@ -37,6 +37,7 @@ const LabelComponent = React.forwardRef(({ children,upperCase,testID,wrap,native
|
|
|
37
37
|
if(underlined){
|
|
38
38
|
r1.textDecorationLine = 'underline';
|
|
39
39
|
}
|
|
40
|
+
|
|
40
41
|
style = Object.assign({},StyleSheet.flatten(style));
|
|
41
42
|
testID = defaultStr(testID,"RN_LabelComponent");
|
|
42
43
|
const restProps = {nativeID};
|
|
@@ -57,6 +58,9 @@ const LabelComponent = React.forwardRef(({ children,upperCase,testID,wrap,native
|
|
|
57
58
|
children = children.toUpperCase();
|
|
58
59
|
}
|
|
59
60
|
}
|
|
61
|
+
if(fontSize){
|
|
62
|
+
r1.fontSize = fontSize;
|
|
63
|
+
}
|
|
60
64
|
return (<Text allowFontScaling = {true} ref = {ref} selectable={defaultSelectable} {...rest} {...restProps} testID={testID} disabled={disabled} style={[styles.label,splitText?styles.wrap:null,splitText?styles.w100:null,bold?styles.bold:null,r2,style,r1,styles.webFontFamilly]}>{children}</Text>)
|
|
61
65
|
}
|
|
62
66
|
let hasP = false;
|
|
@@ -91,6 +95,7 @@ LabelComponentExported.propTypes = {
|
|
|
91
95
|
children : PropTypes.any,
|
|
92
96
|
upperCase: PropTypes.bool,///si la transformation sera en majuscule
|
|
93
97
|
text : PropTypes.any,
|
|
98
|
+
fontSize : PropTypes.number,
|
|
94
99
|
wrap : PropTypes.bool, //si le texte sera splité vers la ligne suivantes
|
|
95
100
|
wrapText : PropTypes.bool,///alias à wrap
|
|
96
101
|
primary : PropTypes.bool,
|
|
@@ -21,6 +21,7 @@ import theme from "$theme";
|
|
|
21
21
|
import cActions from "$cactions";
|
|
22
22
|
import APP from "$capp/instance";
|
|
23
23
|
import { generatedColumnsProperties } from "./utils";
|
|
24
|
+
import i18n from "$i18n";
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
const HIDE_PRELOADER_TIMEOUT = 300;
|
|
@@ -86,6 +87,39 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
86
87
|
Object.map(table.fields,(field,i)=>{
|
|
87
88
|
if(isObj(field) && field.form !== false){
|
|
88
89
|
fields[i] = Object.clone(field);
|
|
90
|
+
const f = fields[i];
|
|
91
|
+
f.type = defaultStr(f.jsType,f.type).toLowerCase();
|
|
92
|
+
const name = f.field = defaultStr(f.field,i);
|
|
93
|
+
if((f.type =='id' || f.type =='piece' || f.unique === true) && f.unique !== false && f.disabled !== true && f.editable !== false && f.readOnly !== true){
|
|
94
|
+
const {onBlur} = f;
|
|
95
|
+
f.onBlur = (args)=>{
|
|
96
|
+
args = {...f,...args,columnField:name,fieldName:name,id:args.value};
|
|
97
|
+
const {context} = args;
|
|
98
|
+
const r = typeof onBlur =='function'? onBlur (args) : undefined;
|
|
99
|
+
if(r === false) return r;
|
|
100
|
+
//on applique la validation seulement en cas de non mise à jour
|
|
101
|
+
if(!this.isDocEditingRef.current && context && typeof context.onNoValidate =='function'){
|
|
102
|
+
const cb = typeof field.fetchUniqueId =='function'? field.fetchUniqueId : typeof this.fetchUniqueId =='function'? this.fetchUniqueId : undefined;
|
|
103
|
+
if(cb){
|
|
104
|
+
const r2 = cb(args);
|
|
105
|
+
if(isPromise(r2)){
|
|
106
|
+
r2.then((data)=>{
|
|
107
|
+
let message = data;
|
|
108
|
+
if(isObj(data) && Object.size(data,true)){
|
|
109
|
+
message = i18n.lang('validate_rule_field_must_be_unique')+ defaultStr(f.label,f.text);
|
|
110
|
+
}
|
|
111
|
+
if(isNonNullString(message)){
|
|
112
|
+
context.onNoValidate({...args,msg:message,message,context,validRule:context.getValidRule()});
|
|
113
|
+
}
|
|
114
|
+
}).catch((e)=>{
|
|
115
|
+
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return r;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
89
123
|
if(field.primaryKey === true){
|
|
90
124
|
primaryKeyFields[field.field || i] = true;
|
|
91
125
|
}
|
|
@@ -98,6 +132,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
98
132
|
tableName : { value : defaultStr(table.table,table.tableName)},
|
|
99
133
|
fields : {value : fields},
|
|
100
134
|
table : {value : table},
|
|
135
|
+
isDocEditingRef : {value : {current:false}},
|
|
101
136
|
validateDataBeforeSave : {value : mainProps.validateData},
|
|
102
137
|
upsertDataToDB : {value : mainProps.upsertToDB},
|
|
103
138
|
makePhoneCallProps : {value : mainProps.makePhoneCallProps},
|
|
@@ -105,6 +140,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
105
140
|
titleProp : {value : mainProps.title},
|
|
106
141
|
closeOnSaveProp : {value : mainProps.closeOnSave || mainProps.closeAfterSave },
|
|
107
142
|
newActionProp : {value : mainProps.newAction},
|
|
143
|
+
fetchUniqueId : {value : mainProps.fetchUniqueId},
|
|
108
144
|
//la liste des champ de type clé primaire associés à la table
|
|
109
145
|
primaryKeyFields : {value : primaryKeyFields},
|
|
110
146
|
cloneProp : {value : typeof mainProps.clone =='function' && mainProps.clone || undefined},
|
|
@@ -195,6 +231,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
195
231
|
const tableName = this.tableName;
|
|
196
232
|
const sessionName = this.INITIAL_STATE.sessionName = defaultStr(customSessionName,"table-form-data"+tableName);
|
|
197
233
|
const isUpdated = this.isDocEditing(data);
|
|
234
|
+
this.isDocEditingRef.current = isUpdated;
|
|
198
235
|
const isMobOrTab = isMobileOrTabletMedia();
|
|
199
236
|
let archived = this.isArchived();
|
|
200
237
|
this.INITIAL_STATE.archived = archived;
|
|
@@ -755,6 +792,8 @@ TableDataScreenComponent.propTypes = {
|
|
|
755
792
|
table : PropTypes.string,
|
|
756
793
|
fields : PropTypes.object,
|
|
757
794
|
}),
|
|
795
|
+
unique : PropTypes.bool,//si la validation de type unique sur le champ sera effective
|
|
796
|
+
fetchUniqueId : PropTypes.func,//la fonction permettant de fetch un élément unique pour la validation de type uniqueID, liée aux champs de type piece et id
|
|
758
797
|
validateData : PropTypes.func,// la fonction permettant de valider les données à enregistrer
|
|
759
798
|
archivedPermsFilter : PropTypes.func,///le filtre des permissions archivées
|
|
760
799
|
newElementLabel : PropTypes.string,//le titre du bouton nouveau pour l'ajout d'un nouvel élément
|