@fto-consult/expo-ui 2.12.0 → 2.12.2

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.12.0",
3
+ "version": "2.12.2",
4
4
  "description": "Bibliothèque de composants UI Expo,react-native",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -65,7 +65,7 @@
65
65
  "@expo/metro-config": "^0.4.0",
66
66
  "@expo/vector-icons": "^13.0.0",
67
67
  "@expo/webpack-config": "^0.17.2",
68
- "@fto-consult/common": "^1.20.1",
68
+ "@fto-consult/common": "^1.20.2",
69
69
  "@gorhom/portal": "^1.0.14",
70
70
  "@react-native-async-storage/async-storage": "~1.17.3",
71
71
  "@react-native-community/datetimepicker": "6.5.2",
@@ -20,7 +20,7 @@ export const getCountryFieldProps = (props)=>{
20
20
  items : countries,
21
21
  upper : true,
22
22
  dialogProps : {title:'Sélectionner un pays'},
23
- getItemValue : ({item})=>item.code,
23
+ getItemValue : ({item})=>item.code.toUpperCase(),
24
24
  renderText : ({item})=>"[{0}] {1}".sprintf(item?.code?.toUpperCase(),item?.label),
25
25
  compare : (a,b)=>{
26
26
  return typeof a ==='string' && typeof b =='string' && a.toLowerCase() === b.toLowerCase() ? true : false;
@@ -677,9 +677,20 @@ export default class Field extends AppComponent {
677
677
  return true;
678
678
  }
679
679
  onBlurField(event){
680
- if(isFunction(this.props.onBlur)){
681
- this.props.onBlur({event,context:this})
680
+ if(isFunction(this.props.onBlur) && this.props.onBlur({event,context:this}) === false){
681
+ return;
682
682
  }
683
+ if(this.isFilter()) return
684
+ const value = this.getValue();
685
+ if(isNonNullString(this.props.fieldToPopulateOnBlur) && isNonNullString(value)){
686
+ const context = this.getField(this.props.fieldToPopulateOnBlur.trim());
687
+ if(context && context.getValue){
688
+ const cVal = defaultStr(context.getValue());
689
+ if(cVal.length < value.length){
690
+ context.setValue(value);
691
+ }
692
+ }
693
+ }
683
694
  }
684
695
  onFocusField(event){
685
696
  if(isFunction(this.props.onFocus)){
@@ -772,6 +783,7 @@ export default class Field extends AppComponent {
772
783
  width,
773
784
  height,
774
785
  jsType,
786
+ fieldToPopulateOnBlur,
775
787
  ...rest
776
788
  } = this.props;
777
789
  if(this.state.caughtAnError){
@@ -1043,6 +1055,10 @@ Field.propTypes = {
1043
1055
  * Lorsqu'elle est définie alors le rendu lors du composant doit être de type filter
1044
1056
  */
1045
1057
  renderfilter : PropTypes.string,
1058
+ /**** il s'agit d'un champ du même formulaire que la formField actuel, qui sera populated avec la valeur par défaut
1059
+ * de la formField cournat loreque la valeur du champ en question a une longueur très inférieure à celle de la valeur de la form courante.
1060
+ */
1061
+ fieldToPopulateOnBlur : PropTypes.string,
1046
1062
  /*** cette fonction doit retourner l'instance de la field
1047
1063
  elle doit toujours être définie dans la classe qui hérite directement au composant Field
1048
1064
  */
@@ -36,7 +36,7 @@ const TableDataSelectField = React.forwardRef((_props,ref)=>{
36
36
  const [state,setState] = React.useState({
37
37
  items : [],isLoading : true,
38
38
  });
39
- fetchDataOpts = Object.assign({},fetchDataOpts);
39
+ fetchDataOpts = Object.clone(defaultObj(fetchDataOpts));
40
40
  fetchItems = typeof fetchItems =='function' ? fetchItems : typeof fKeyTable.queryPath =='string' ? (opts)=>{
41
41
  return fetch(fKeyTable.queryPath,opts);
42
42
  } : undefined;
@@ -92,10 +92,12 @@ const TableDataSelectField = React.forwardRef((_props,ref)=>{
92
92
  const context = {
93
93
  refresh : (force,cb)=>{
94
94
  if(!isMounted()) return;
95
+ if(typeof beforeFetchItems ==='function' && beforeFetchItems(fetchDataOpts) === false) return;
95
96
  let opts = Object.clone(fetchDataOpts);
96
97
  opts.selector = prepareFilters(fetchDataOpts.selector,{convertToSQL:convertFiltersToSQL});
97
98
  opts = getFetchOptions(opts);
98
99
  const r = fetchItems && fetchItems(opts);
100
+ if(r === false) return;
99
101
  if(isPromise(r)){
100
102
  r.then((args)=>{
101
103
  if(Array.isArray(args)){
@@ -208,6 +210,7 @@ TableDataSelectField.propTypes = {
208
210
  ...Dropdown.propTypes,
209
211
  mutateFetchedItems : PropTypes.func, //la fonction permettant d'effectuer une mutation sur l'ensemble des donnéees récupérées à distance
210
212
  fetchItems : PropTypes.func,//la fonction de rappel à utiliser pour faire une requête fetch permettant de selectionner les données à distance
213
+ beforeFetchItems : PropTypes.func, //appelée immédiatement avant l'exécution de la requête fetch
211
214
  foreignKeyColumn : PropTypes.string.isRequired,//le nom de la clé étrangère à laquelle fait référence la colone dans la fKeyTable
212
215
  foreignKeyLabel : PropTypes.string,
213
216
  getForeignKeyTable : PropTypes.func.isRequired, //la fonction permettant de récupérer la fKeyTable data dont fait référence le champ
@@ -11,6 +11,12 @@ export default class FormSelectTableDataField extends SelectField{
11
11
  this.props.onChange(args);
12
12
  }
13
13
  }}
14
+ beforeFetchItems = {(opts)=>{
15
+ if(typeof props.beforeFetchItems =='function'){
16
+ return props.beforeFetchItems({...opts,context:this,dropdownContext : this._field})
17
+ }
18
+ return true;
19
+ }}
14
20
  ref = {(el)=>{
15
21
  this._field = el;
16
22
  }}
@@ -1,5 +1,6 @@
1
1
  import _ from 'lodash';
2
2
  import libPhoneNumber from 'google-libphonenumber';
3
+ import {isNonNullString,defaultStr} from "$cutils";
3
4
 
4
5
  import Country from './country';
5
6
  import numberType from './numberType.json'; // eslint-disable-line @typescript-eslint/no-unused-vars
@@ -10,7 +11,7 @@ const asYouTypeFormatter = libPhoneNumber.AsYouTypeFormatter;
10
11
 
11
12
  export const parse = (number,iso2)=>{
12
13
  try {
13
- return phoneUtil.parse(number, iso2);
14
+ return phoneUtil.parse(number, defaultStr(iso2).toLowerCase());
14
15
  } catch (err) {
15
16
  console.log(`Exception was thrown on parsing phone number : ${err.toString()}`);
16
17
  return null;
@@ -18,7 +19,7 @@ export const parse = (number,iso2)=>{
18
19
  }
19
20
 
20
21
  export const isValidNumber = (number,iso2)=>{
21
- const phoneInfo = parse(number, iso2);
22
+ const phoneInfo = parse(number, defaultStr(iso2).toLowerCase());
22
23
  if (phoneInfo) {
23
24
  return phoneUtil.isValidNumber(phoneInfo);
24
25
  }
@@ -83,16 +84,16 @@ class PhoneNumber {
83
84
 
84
85
  // eslint-disable-next-line class-methods-use-this
85
86
  parse(number, iso2) {
86
- return parse(number,iso2);
87
+ return parse(number,defaultStr(iso2).toLowerCase());
87
88
  }
88
89
 
89
90
  isValidNumber(number, iso2) {
90
- return this.isValidNumber(number,iso2);
91
+ return this.isValidNumber(number,defaultStr(iso2).toLowerCase());
91
92
  }
92
93
 
93
94
  // eslint-disable-next-line class-methods-use-this
94
95
  format(number, iso2) {
95
- const formatter = new asYouTypeFormatter(iso2); // eslint-disable-line new-cap
96
+ const formatter = new asYouTypeFormatter(defaultStr(iso2).toLowerCase()); // eslint-disable-line new-cap
96
97
  let formatted;
97
98
  number.replace(/-/g, '')
98
99
  .replace(/ /g, '')
@@ -107,14 +108,14 @@ class PhoneNumber {
107
108
  }
108
109
 
109
110
  getNumberType(number, iso2) {
110
- const phoneInfo = this.parse(number, iso2);
111
+ const phoneInfo = this.parse(number, defaultStr(iso2).toLowerCase());
111
112
  const typeIndex = phoneInfo ? phoneUtil.getNumberType(phoneInfo) : -1;
112
113
  return _.findKey(numberType, (noType) => noType === typeIndex);
113
114
  }
114
115
 
115
116
  // eslint-disable-next-line class-methods-use-this
116
117
  getCountryDataByCode(iso2) {
117
- return Country.getCountryDataByCode(iso2);
118
+ return Country.getCountryDataByCode(defaultStr(iso2).toLowerCase());
118
119
  }
119
120
  }
120
121
 
@@ -20,6 +20,8 @@ import {renderTabsContent,renderActions} from "./utils";
20
20
  import theme from "$theme";
21
21
  import cActions from "$cactions";
22
22
  import APP from "$capp/instance";
23
+ import { generatedColumnsProperties } from "./utils";
24
+
23
25
 
24
26
  const HIDE_PRELOADER_TIMEOUT = 300;
25
27
 
@@ -164,6 +166,13 @@ export default class TableDataScreenComponent extends FormDataScreen{
164
166
  Object.map(this.fields,(field,i)=>{
165
167
  if(isObj(field)){
166
168
  fields[i] = Object.clone(field);
169
+ generatedColumnsProperties.map((f)=>{
170
+ //on affiche les champs générés uniquement en cas de mise à jour
171
+ if(field[f] === true){
172
+ fields[f].visible = isUpdated ? true : false;
173
+ fields[i].readOnly = true;
174
+ }
175
+ });
167
176
  if(isUpdated){
168
177
  //la props readOnlyOnEditing permet de rendre le champ readOnly en cas de mise à jour de la tableData
169
178
  if((field.readOnlyOnEditing === true)){
@@ -173,6 +182,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
173
182
  fields[i].disabled = true;
174
183
  }
175
184
  }
185
+
176
186
  } else {
177
187
  fields[i] = field;
178
188
  }
@@ -438,7 +448,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
438
448
  if(this.cloneProp && this.cloneProp(data,this) === false) return data;
439
449
  this.showPreloader();
440
450
  delete data.approved;
441
- Object.map(['_rev','_id','code','updatedBy','updatedDate','createdBy','updatedHour','createdHour','createdDate'],(idx)=>{
451
+ Object.map(['_rev',...generatedColumnsProperties,'_id','code','updateBy','updatedDate','createBy','updatedHour','createdHour','createdDate'],(idx)=>{
442
452
  data[idx] = undefined;
443
453
  delete data[idx];
444
454
  });
@@ -5,6 +5,8 @@ import {Colors} from "$theme";
5
5
  import { COPY_ICON,PRINT_ICON} from "$ecomponents/Icon";
6
6
  import {getTableDataRouteName} from "$enavigation/utils";
7
7
 
8
+ //@seee : https://github.com/typeorm/typeorm/blob/master/src/entity-schema/EntitySchemaColumnOptions.ts
9
+ export const generatedColumnsProperties = ["createDate","updateDate","deleteDate","createBy","updateBy","deleteBy"]
8
10
 
9
11
  export const renderTabsContent = ({tabs,context,data,sessionName,isMobile,props,firstTab,tabKey,tabProps,tabsProps})=>{
10
12
  let tabsArr = [],hasFirstTab = false;