@fto-consult/expo-ui 8.76.8 → 8.77.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.
@@ -47,9 +47,17 @@ export default {
47
47
  la fonction loginPropsMutator de muter les props du composant Login par défaut, prise en compte lorsque le composant de connexion n'est pas remplacer par celui définit dans la prop login,
48
48
  @param {object} props : les propriétés de la fonction login, les props ont des propriétés suivantes :
49
49
  {
50
+ signIn : ()=><any>, la fonction permettant de connecter l'utilisateur,
50
51
  onSuccess : ({object})=><Any>, la fonction appelée en cas de success
51
52
  setState : (newState)=>(...newState),//la fonction utilisée pour update le state du composant. elle doit remplacer le state du composant
52
- state : <Object: data,...rest>, le state actuel à l'instant t du composant
53
+ state : <Object: data,...rest>, le state actuel à l'instant t du composant,
54
+
55
+ //prend en paramètre une référence pointant sur le composant $ecomponents/Button et retourne les actions possible sur ledit button
56
+ getButtonAction : (buttonRef) => <{
57
+ enable : x=>typeof buttonRef?.current?.enable =="function" && buttonRef.current.enable(),
58
+ disable : x=> typeof buttonRef?.current?.disable =="function" && buttonRef?.current.disable(),
59
+ isDisabled : x=> typeof buttonRef?.current?.isDisabled ==="function" && buttonRef.current?.isDisabled(),
60
+ },
53
61
  nextButton : <Object :
54
62
  {
55
63
  ref : nextButtonRef, //la référence vers le bouton next (le boutn Suivant)
@@ -72,6 +80,7 @@ export default {
72
80
  formName <string>, //le nom du formulaire Form, passé à la formData
73
81
  nextButtonRef <{current:<any>}>, la référence vers le bouton next
74
82
  previousButtonRef <{current:<any>}, la référence vers le bouton previous
83
+ formProps : (object), //les props à passer au composant FormData
75
84
  }
76
85
  @return <{object}>, l'objet a retourné doit être de la forme :
77
86
  {
@@ -80,6 +89,8 @@ export default {
80
89
  containerProps : <object>, les props du composant <Surface/>, le composant qui est le wrapper du composant FormData en charge de récupérer les données de l'interface de connexion
81
90
  canSubmit : ({step,...rest})=> <boolean>, //si les donées du formulaire peuvent être submit
82
91
  beforeSubmit : ({step,data,...rest})=><void>, //la fonction appélée immédiatement avant le submit des donénes
92
+ renderNextButton : <boolean>, //si le bouton next sera rendu
93
+ renderPreviousButton : <boolean>, //si le bouton previous sera rendu
83
94
  ...loginProps {object}, les props Supplémentaires à passer au composant FormData utilisé pour le rendu du formulaire de connexion
84
95
  }
85
96
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fto-consult/expo-ui",
3
- "version": "8.76.8",
3
+ "version": "8.77.0",
4
4
  "description": "Bibliothèque de composants UI Expo,react-native",
5
5
  "react-native-paper-doc": "https://github.com/callstack/react-native-paper/tree/main/docs/docs/guides",
6
6
  "scripts": {
package/src/auth/Login.js CHANGED
@@ -2,6 +2,7 @@ import React from "$react";
2
2
  import {isNonNullString,isObj,defaultNumber,defaultStr,uniqid,extendObj,isFunction} from "$cutils";
3
3
  import {navigate} from "$cnavigation";
4
4
  import FormData from "$ecomponents/Form/FormData/FormData";
5
+ import { Action } from "$ecomponents/Form";
5
6
  import {getForm} from "$ecomponents/Form/utils";
6
7
  import Button from "$ecomponents/Button";
7
8
  import notify from "$notify";
@@ -106,23 +107,76 @@ export default function LoginComponent(props){
106
107
  onSuccess = {onSuccess}
107
108
  auth = {auth}
108
109
  />
109
- const getButtonAction = (buttonRef)=>{
110
- return {
111
- ref : buttonRef,
112
- isDisabled : x=> typeof buttonRef?.current?.isDisabled ==="function" && buttonRef.current?.isDisabled(),
113
- enable : x=>typeof buttonRef?.current?.enable =="function" && buttonRef.current.enable(),
114
- disable : x=> typeof buttonRef?.current?.disable =="function" && buttonRef?.current.disable(),
110
+ const getButtonAction = React.useMemo(()=>{
111
+ return (buttonRef)=>{
112
+ buttonRef = buttonRef || React.createRef();
113
+ return {
114
+ ref : buttonRef,
115
+ isDisabled : x=> typeof buttonRef?.current?.isDisabled ==="function" && buttonRef.current?.isDisabled(),
116
+ enable : x=>{
117
+ return typeof buttonRef?.current?.enable =="function" && buttonRef.current.enable();
118
+ },
119
+ disable : x=> {
120
+ return typeof buttonRef?.current?.disable =="function" && buttonRef?.current.disable()
121
+ },
122
+ }
115
123
  }
116
- }
124
+ },[]);
117
125
  const nextButton = getButtonAction(nextButtonRef),
118
126
  prevButton = getButtonAction(previousButtonRef);
119
- const {header,
127
+ const setIsLoading = (buttonRef,bool)=>{
128
+ if(typeof buttonRef?.current?.setIsLoading == 'function'){
129
+ return buttonRef.current?.setIsLoading(bool)
130
+ }
131
+ }
132
+ const beforeSubmitRef = React.useRef(null);
133
+ const canSubmitRef = React.useRef(null);
134
+ const mutateDataRef = React.useRef(null);
135
+ const signIn = ()=>{
136
+ const canSubmit = typeof canSubmitRef.current == 'function'? canSubmitRef.current : w=>true;
137
+ const cS = canSubmit(args);
138
+ if(typeof cS === 'string' && cS){
139
+ return notifyUser(cS);
140
+ }
141
+ const data = getData();
142
+ const form = _getForm();
143
+ if(!form){
144
+ notifyUser("Impossible de valider le formulaire car celui-ci semble invalide")
145
+ return;
146
+ }
147
+ if(!form.isValid()){
148
+ notifyUser(form.getErrorText());
149
+ return;
150
+ }
151
+ const args = {...state,data,form,state,step,setState,nextButtonRef,previousButtonRef};
152
+ const beforeSubmit = typeof beforeSubmitRef.current === 'function' ? beforeSubmitRef.current : ()=> true;
153
+ if(cS && beforeSubmit(args) !== false){
154
+ Preloader.open("vérification ...");
155
+ setIsLoading(nextButtonRef,true);
156
+ return auth.signIn(data).then((a)=>{
157
+ if(typeof onLoginSuccess =='function' && onLoginSuccess(a)=== false) return;
158
+ if(isFunction(onSuccess)){
159
+ onSuccess(data);
160
+ } else {
161
+ navigate("Home");
162
+ }
163
+ }).finally(()=>{
164
+ Preloader.close();
165
+ setIsLoading(nextButtonRef,false);
166
+ })
167
+ }
168
+ }
169
+ const {header : Header,
120
170
  headerTopContent:HeaderTopContent,
121
171
  containerProps : customContainerProps,
122
172
  contentProps : customContentProps,
123
- withScrollView:customWithScrollView,children,initialize,contentTop,data:loginData,canGoToNext,keyboardEvents,onSuccess:onLoginSuccess,mutateData,beforeSubmit:beforeSubmitForm,canSubmit:canSubmitForm,onStepChange,...loginProps} = loginPropsMutator({
173
+ formProps,
174
+ withScrollView:customWithScrollView,children,initialize,contentTop,renderNextButton,renderPreviousButton,data:loginData,canGoToNext,keyboardEvents,onSuccess:onLoginSuccess,beforeSubmit:beforeSubmitForm,canSubmit:canSubmitForm,onStepChange,...loginProps} = loginPropsMutator({
124
175
  ...state,
176
+ getButtonAction,
177
+ signIn,
125
178
  setState,
179
+ setIsLoading,
126
180
  state,
127
181
  nextButton,
128
182
  prevButton,
@@ -143,8 +197,9 @@ export default function LoginComponent(props){
143
197
  /****la fonction à utiliser pour vérifier si l'on peut envoyer les données pour connextion
144
198
  * par défaut, on envoie les données lorssqu'on est à l'étappe 2
145
199
  * **/
146
- const canSubmit = typeof canSubmitForm =='function'? canSubmitForm : ({step})=>step >= 2;
147
- const beforeSubmit = typeof beforeSubmitForm =='function'? beforeSubmitForm : x=> true;
200
+ canSubmitRef.current = typeof canSubmitForm =='function'? canSubmitForm : ({step})=>step >= 2;
201
+ beforeSubmitRef.current = typeof beforeSubmitForm =='function'? beforeSubmitForm : x=> true;
202
+
148
203
  const goToNext = ()=>{
149
204
  let step = state.step;
150
205
  const data = getData();
@@ -175,27 +230,7 @@ export default function LoginComponent(props){
175
230
  nextButtonRef.current?.enable();
176
231
  }
177
232
  if(step > 1){
178
- const cS = canSubmit(args);
179
- if(typeof cS === 'string' && cS){
180
- return notifyUser(cS);
181
- }
182
- if(cS && beforeSubmit(args) !== false){
183
- ///pour modifier automatiquement la données à mettre à jour
184
- if(typeof mutateData =='function'){
185
- mutateData(data);
186
- }
187
- Preloader.open("vérification ...");
188
- return auth.signIn(data).then((a)=>{
189
- if(typeof onLoginSuccess =='function' && onLoginSuccess(a)=== false) return;
190
- if(isFunction(onSuccess)){
191
- onSuccess(data);
192
- } else {
193
- navigate("Home");
194
- }
195
- }).finally(()=>{
196
- Preloader.close();
197
- })
198
- }
233
+ signIn();
199
234
  } else {
200
235
  setState({...state,step:step+1,data})
201
236
  }
@@ -221,6 +256,7 @@ export default function LoginComponent(props){
221
256
  };
222
257
  const wrapperProps = withPortal ? {appBarProps,authRequired:false,title:loginTitle,withScrollView} : { style:styles.wrapper};
223
258
  const sH = React.isComponent(HeaderTopContent)? <HeaderTopContent mediaQueryUpdateStyle = {mediaQueryUpdateStyle} /> : React.isValidElement(HeaderTopContent)? HeaderTopContent : null;
259
+ const header = React.isComponent(Header) ? <Header mediaQueryUpdateStyle = {mediaQueryUpdateStyle}/> : React.isValidElement(Header)? Header : null;
224
260
  return <Wrapper testID = {testID+"_Wrapper" }{...wrapperProps}>
225
261
  <DialogProvider ref={dialogProviderRef}/>
226
262
  {sH}
@@ -237,22 +273,23 @@ export default function LoginComponent(props){
237
273
  responsive = {false}
238
274
  {...loginProps}
239
275
  fields = {loginFields}
240
- formProps = {{
276
+ formProps = {extendObj(true,{},{
241
277
  keyboardEvents : {
242
- ...defaultObj(keyboardEvents),
243
278
  enter : ({formInstance})=>{
244
279
  goToNext();
245
- }
280
+ },
246
281
  }
247
- }}
282
+ },formProps)}
248
283
  data = {extendObj(state.data,loginData)}
249
284
  >
250
285
  <>
251
286
  {React.isValidElement(contentTop)? contentTop : null}
252
- {hasLoginFields?<View testID={testID+"_ButtonsContainer"} style={[styles.buttonWrapper]}>
253
- <Button
287
+ {renderNextButton !== false || renderPreviousButton !== false ? <>
288
+ {hasLoginFields?<View testID={testID+"_ButtonsContainer"} style={[styles.buttonWrapper]}>
289
+ {renderNextButton !== false ? <Action
254
290
  ref = {nextButtonRef}
255
291
  primary
292
+ formName={formName}
256
293
  mode = "contained"
257
294
  rounded
258
295
  style = {styles.button}
@@ -261,8 +298,8 @@ export default function LoginComponent(props){
261
298
  surface
262
299
  >
263
300
  {state.step == 1? 'Suivant' : 'Connexion' }
264
- </Button>
265
- {state.step>=2 ? <Button
301
+ </Action> : null}
302
+ {renderPreviousButton !== false && state.step>=2 ? <Button
266
303
  onPress = {goToFirstStep}
267
304
  ref = {previousButtonRef}
268
305
  mode = "contained"
@@ -276,6 +313,7 @@ export default function LoginComponent(props){
276
313
  Précédent
277
314
  </Button> : null}
278
315
  </View> : null}
316
+ </> : null}
279
317
  </>
280
318
  </FormData>
281
319
  {React.isValidElement(children) ? children : null}
@@ -352,7 +390,10 @@ LoginComponent.propTypes = {
352
390
  header : PropTypes.oneOfType([
353
391
  PropTypes.node,
354
392
  PropTypes.element,
393
+ PropTypes.func,
355
394
  ]),
395
+ renderNextButton : PropTypes.bool,//si le bouton next sera rendu
396
+ renderPreviousButton : PropTypes.bool,//si le bouton previous sera rendu
356
397
  }
357
398
 
358
399
  /*** les loginProps sont les porps à passer au composant FormData
@@ -655,7 +655,7 @@ export default class Field extends AppComponent {
655
655
  let {keyboardEvents,onKeyEvent} = this.props;
656
656
  const formInstance = this.getForm();
657
657
  const data = formInstance ? formInstance.getData() : {};
658
- const arg = {key,event,formInstance,field:this.name,formName:this.getFormName(),value:this.getValidRule(),validValue:this.getValidValue(data),data,context:this,isFormField:true,formInstance};
658
+ const arg = {key,event,formInstance,form:formInstance,field:this.name,formName:this.getFormName(),value:this.getValidRule(),validValue:this.getValidValue(data),data,context:this,isFormField:true,formInstance};
659
659
  let handler = undefined;
660
660
  if(isObj(keyboardEvents)){
661
661
  handler = keyboardEvents[key];