@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fto-consult/expo-ui",
3
- "version": "2.14.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.1",
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
- {...defaultObj(rest)}
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 testID={testID+"_Label"} style={[{fontSize:15}]}>
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);
@@ -390,7 +390,8 @@ const styles = StyleSheet.create({
390
390
  flexDirection : 'row',
391
391
  width : '100%',
392
392
  justifyContent : 'flex-end',
393
- alignItems : 'center'
393
+ alignItems : 'center',
394
+ paddingHorizontal : 10,
394
395
  },
395
396
  hidden : {
396
397
  display : 'none',
@@ -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