@fto-consult/expo-ui 2.14.3 → 2.15.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fto-consult/expo-ui",
3
- "version": "2.14.3",
3
+ "version": "2.15.1",
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){
@@ -274,7 +274,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
274
274
  style = {sStyle}
275
275
  anchor = {(p)=>{
276
276
  return <Pressable style={[theme.styles.noMargin,theme.styles.noPadding]} {...p} testID={testID+"MenuSelectLimit"}>
277
- <Label primary testID={testID+"_Label"} style={[{fontSize:15}]}>
277
+ <Label primary testID={testID+"_Label"} fontSize={16}>
278
278
  {limitRef.current.formatNumber()}
279
279
  </Label>
280
280
  </Pressable>
@@ -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,8 @@ 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";
25
+ import fetch from "$capi/fetch";
24
26
 
25
27
 
26
28
  const HIDE_PRELOADER_TIMEOUT = 300;
@@ -86,6 +88,39 @@ export default class TableDataScreenComponent extends FormDataScreen{
86
88
  Object.map(table.fields,(field,i)=>{
87
89
  if(isObj(field) && field.form !== false){
88
90
  fields[i] = Object.clone(field);
91
+ const f = fields[i];
92
+ f.type = defaultStr(f.jsType,f.type).toLowerCase();
93
+ const name = f.field = defaultStr(f.field,i);
94
+ if((f.type =='id' || f.type =='piece' || f.unique === true) && f.unique !== false && f.disabled !== true && f.editable !== false && f.readOnly !== true){
95
+ const {onBlur} = f;
96
+ f.onBlur = (args)=>{
97
+ args = {...f,...args,fetch,columnField:name,fieldName:name,id:args.value};
98
+ const {context} = args;
99
+ const r = typeof onBlur =='function'? onBlur (args) : undefined;
100
+ if(r === false) return r;
101
+ //on applique la validation seulement en cas de non mise à jour
102
+ if(!this.isCurrentDocEditingUpdate() && context && typeof context.onNoValidate =='function'){
103
+ const cb = typeof field.fetchUniqueId =='function'? field.fetchUniqueId : typeof this.fetchUniqueId =='function'? this.fetchUniqueId : undefined;
104
+ if(cb){
105
+ const r2 = cb(args);
106
+ if(isPromise(r2)){
107
+ r2.then((data)=>{
108
+ let message = data;
109
+ if(isObj(data) && Object.size(data,true)){
110
+ message = i18n.lang('validate_rule_field_must_be_unique')+ defaultStr(f.label,f.text);
111
+ }
112
+ if(isNonNullString(message)){
113
+ context.onNoValidate({...args,msg:message,message,context,validRule:context.getValidRule()});
114
+ }
115
+ }).catch((e)=>{
116
+
117
+ })
118
+ }
119
+ }
120
+ }
121
+ return r;
122
+ }
123
+ }
89
124
  if(field.primaryKey === true){
90
125
  primaryKeyFields[field.field || i] = true;
91
126
  }
@@ -98,6 +133,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
98
133
  tableName : { value : defaultStr(table.table,table.tableName)},
99
134
  fields : {value : fields},
100
135
  table : {value : table},
136
+ isDocEditingRef : {value : {current:false}},
101
137
  validateDataBeforeSave : {value : mainProps.validateData},
102
138
  upsertDataToDB : {value : mainProps.upsertToDB},
103
139
  makePhoneCallProps : {value : mainProps.makePhoneCallProps},
@@ -105,6 +141,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
105
141
  titleProp : {value : mainProps.title},
106
142
  closeOnSaveProp : {value : mainProps.closeOnSave || mainProps.closeAfterSave },
107
143
  newActionProp : {value : mainProps.newAction},
144
+ fetchUniqueId : {value : mainProps.fetchUniqueId},
108
145
  //la liste des champ de type clé primaire associés à la table
109
146
  primaryKeyFields : {value : primaryKeyFields},
110
147
  cloneProp : {value : typeof mainProps.clone =='function' && mainProps.clone || undefined},
@@ -116,6 +153,9 @@ export default class TableDataScreenComponent extends FormDataScreen{
116
153
  this.hidePreloader = this.hidePreloader.bind(this);
117
154
  this.showPreloader = this.showPreloader.bind(this);
118
155
  };
156
+ isCurrentDocEditingUpdate(){
157
+ return this.isDocEditingRef.current === true ? true : false;
158
+ }
119
159
  resetState(){
120
160
  Object.map(this.INITIAL_STATE,(s,k)=>{
121
161
  delete this.INITIAL_STATE[k];
@@ -195,6 +235,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
195
235
  const tableName = this.tableName;
196
236
  const sessionName = this.INITIAL_STATE.sessionName = defaultStr(customSessionName,"table-form-data"+tableName);
197
237
  const isUpdated = this.isDocEditing(data);
238
+ this.isDocEditingRef.current = !!isUpdated;
198
239
  const isMobOrTab = isMobileOrTabletMedia();
199
240
  let archived = this.isArchived();
200
241
  this.INITIAL_STATE.archived = archived;
@@ -361,7 +402,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
361
402
  }
362
403
  } else {
363
404
  mainContent = <Surface {...contentProps} testID={testID+"_MainContentContainer"} elevation={elevation} style={[styles.container,styles.noPadding,{paddingTop:0,marginTop:0}]}>
364
- <ScrollView virtualized testID={testID+"_MainContentScrollView"}>
405
+ <ScrollView virtualized testID={testID+"_MainContentScrollViewWithoutTab"}>
365
406
  <View testID={testID+"_MainContent"} style={[styles.screenContent,!isMobOrTab && theme.styles.p1,header?styles.screenContentWithHeader:null]}>
366
407
  {header}
367
408
  {content}
@@ -755,6 +796,8 @@ TableDataScreenComponent.propTypes = {
755
796
  table : PropTypes.string,
756
797
  fields : PropTypes.object,
757
798
  }),
799
+ unique : PropTypes.bool,//si la validation de type unique sur le champ sera effective
800
+ 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
801
  validateData : PropTypes.func,// la fonction permettant de valider les données à enregistrer
759
802
  archivedPermsFilter : PropTypes.func,///le filtre des permissions archivées
760
803
  newElementLabel : PropTypes.string,//le titre du bouton nouveau pour l'ajout d'un nouvel élément
@@ -3,7 +3,6 @@
3
3
  // license that can be found in the LICENSE file.
4
4
  import {navigate,sanitizeName} from "$cnavigation";
5
5
  import {isNonNullString,defaultObj,isObj} from "$utils";
6
-
7
6
  export const tableDataRouteName = 'TableData';
8
7
 
9
8
  export const navigateToTableData = function(tableName,params,actionType){
@@ -54,6 +53,9 @@ export const getTableDataListRouteName = function(tableName){
54
53
  export const navigateToTableDataList = function (tableName,params){
55
54
  const route = getTableDataListRouteName(tableName);
56
55
  if(isNonNullString(route)){
56
+ if(!Auth.isTableDataAllowed({table:tableName,action:'read'})){
57
+ return Auth.showError()
58
+ }
57
59
  return navigate({routeName:route,params});
58
60
  }
59
61
  return false;