@fto-consult/expo-ui 6.14.0 → 6.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": "6.14.0",
3
+ "version": "6.15.1",
4
4
  "description": "Bibliothèque de composants UI Expo,react-native",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -98,7 +98,7 @@
98
98
  "react-native-gesture-handler": "^2.12.1",
99
99
  "react-native-iphone-x-helper": "^1.3.1",
100
100
  "react-native-mime-types": "^2.4.0",
101
- "react-native-paper": "^5.9.1",
101
+ "react-native-paper": "^5.10.0",
102
102
  "react-native-paper-dates": "^0.18.12",
103
103
  "react-native-reanimated": "~3.3.0",
104
104
  "react-native-safe-area-context": "4.6.3",
@@ -1249,7 +1249,7 @@ DropdownComponent.propTypes = {
1249
1249
  PropTypes.node,
1250
1250
  PropTypes.func,
1251
1251
  ]), //le contenu enfant à afficher après l'anchor
1252
- /**** les actions supplémentaires à ajouter au menu items */
1252
+ /**** les actions supplémentaires à ajouter au menu items du dropdown */
1253
1253
  dropdownActions : PropTypes.oneOfType([
1254
1254
  PropTypes.arrayOf(PropTypes.object),
1255
1255
  PropTypes.objectOf(PropTypes.object),
@@ -280,7 +280,6 @@ export default class Field extends AppComponent {
280
280
  let form = Forms.getForm(this.formName);
281
281
  this.INITIAL_STATE.onValidate.call(this,{...defaultObj(rest),props:this.props,formName:this.formName,form,name:this.name,field:this.name,value,event,context:this});
282
282
  this.callOnChange({value,event,isValid:true,...rest});
283
-
284
283
  if(form && form.props){
285
284
  if(canEnable){
286
285
  if(isFunction(form.props.onValidate)){
@@ -639,7 +638,6 @@ export default class Field extends AppComponent {
639
638
  return false;
640
639
  }
641
640
  doUpdateMediaQueryStyle(args){
642
- if(args?.currentMedia === this.state.currentMedia) return null;
643
641
  const wrapperStyle = this.getMediaQueryUpdateStyle(args);
644
642
  this.setState({isMobile:args.isMobile,wrapperStyle});
645
643
  }
@@ -127,8 +127,6 @@ export default class FormSelectField extends Field{
127
127
  this.validateWithCallOnChange(args);
128
128
  if(typeof props.onChange =='function'){
129
129
  props.onChange(args);
130
- } else if(this.props.onChange =='function'){
131
- this.props.onChange(args);
132
130
  }
133
131
  }}
134
132
  />
@@ -268,29 +268,29 @@ const TableDataSelectField = React.forwardRef(({foreignKeyColumn,isStructData,ge
268
268
  defaultValue = {foreignKeyColumnValue}
269
269
  dropdownActions = {dropdownActions}
270
270
  context = {context}
271
- itemValue = {(p) => {
271
+ itemValue = {(p,...rest) => {
272
272
  if(typeof props.itemValue ==='function'){
273
- return props.itemValue(p);
273
+ return props.itemValue(p,...rest);
274
274
  }
275
275
  return p.item[foreignKeyColumn];
276
276
  }}
277
- renderItem = {(p) => {
277
+ renderItem = {(p,...rest) => {
278
278
  if(typeof props.renderItem ==='function'){
279
- return props.renderItem(p);
279
+ return props.renderItem(p,...rest);
280
280
  }
281
281
  if(typeof props.renderText =='function'){
282
- return props.renderText(p);
282
+ return props.renderText(p,...rest);
283
283
  }
284
- return rItem(p);
284
+ return rItem(p,...rest);
285
285
  }}
286
- renderText = {(p) => {
286
+ renderText = {(p,...rest) => {
287
287
  if(typeof props.renderText ==='function'){
288
- return props.renderText(p);
288
+ return props.renderText(p,...rest);
289
289
  }
290
290
  if(typeof props.renderItem ==='function'){
291
- return props.renderItem(p);
291
+ return props.renderItem(p,...rest);
292
292
  }
293
- return rItem(p);
293
+ return rItem(p,...rest);
294
294
  }}
295
295
  onAdd = {(args)=>{
296
296
  onAddProps = defaultObj(isFunction(onAddProps)? onAddProps.call(context,{context,foreignKeyTable,dbName,props}) : onAddProps);
@@ -9,8 +9,6 @@ import { StyleSheet } from "react-native";
9
9
  import APP from "$capp/instance";
10
10
  import PropTypes from "prop-types";
11
11
 
12
- const defaultComponentNode = View
13
-
14
12
  /**** règles d'utilisation :
15
13
  1. les forms doivent toujours avoir un nom : chaine de caractère unique pour l'application et non null
16
14
  2. tous les champs (Fields) doivent avoir un name et un formName
@@ -91,8 +89,10 @@ export default class FormComponent extends React.AppComponent {
91
89
  return fields[fieldName] || null;
92
90
  }
93
91
  render (){
92
+ if(isNonNullString(this.props.perm) && !Auth.isAllowedFromStr(this.props.perm)){
93
+ return null;
94
+ }
94
95
  let {
95
- Component,
96
96
  onValidate,
97
97
  onNoValidate,
98
98
  onValidateField,
@@ -105,16 +105,11 @@ export default class FormComponent extends React.AppComponent {
105
105
  testID,
106
106
  ...rest
107
107
  } = this.props;
108
- if(isNonNullString(perm) && !Auth.isAllowedFromStr(perm)){
109
- return null;
110
- }
111
- rest = defaultObj(rest);
112
- const ComponentNode = React.isComponent(Component) && Component || defaultComponentNode;
113
108
  testID = defaultStr(testID,"RN_FormComponent");
114
109
  return (<KeyboardAvoidingView testID={testID+"_KeyboardAvoidingView"}>
115
- <ComponentNode {...rest} testID={testID} style={[styles.container,rest.style]}>
110
+ <View {...rest} testID={testID} style={[styles.container,rest.style]}>
116
111
  {this.props.children}
117
- </ComponentNode>
112
+ </View>
118
113
  </KeyboardAvoidingView>);
119
114
  }
120
115
  }
@@ -5,7 +5,7 @@ import getComponentFromType from "./componentsTypes";
5
5
  import appConfig from "$capp/config";
6
6
  import Colors from "$theme/colors";
7
7
 
8
- const FieldContentComponent = React.forwardRef(({field,data,index,fields,formName,fieldProps,backgroundColor,primaryKey:customPrimaryKey,increment,fieldProp,archivable,disabled,windowWidth,responsive,responsiveProps,archived,...props},ref)=>{
8
+ const FieldContentComponent = React.forwardRef(({field,data,index,fields,formName,onLoopField,fieldProps,backgroundColor,primaryKey:customPrimaryKey,increment,fieldProp,archivable,disabled,windowWidth,responsive,responsiveProps,archived,...props},ref)=>{
9
9
  if(field?.form === false) return null;
10
10
  fieldProp = defaultObj(fieldProp);
11
11
  const name = defaultStr(field.name,field.field,index);
@@ -31,28 +31,31 @@ const FieldContentComponent = React.forwardRef(({field,data,index,fields,formNam
31
31
  if(typeof rest.filter !=='function'){
32
32
  delete rest.filter;
33
33
  }
34
- if(name){
35
- rest.defaultValue = useDefaultValueFromData === false ? defaultValue : (name in data && data[name] !== undefined && data[name] !== null? data[name]: defaultValue);
36
- if((type == 'selecttabledata' || type == 'datafile')){
37
- rest._defaultValue = data[rest.name];
38
- }
39
- } else {
40
- rest.defaultValue = defaultValue;
41
- }
42
- if(rest.defaultValue === null){
43
- rest.defaultValue = undefined;
44
- }
45
- // les champs de type date par défaut qui sont requis, auront comme valeur par défaut la date actuelle s'il ne sont pas définies
46
- if(rest.autoSetDefaultValue !== false && (!rest.defaultValue && typeof rest.defaultValue !=='boolean' && typeof rest.defaultValue !=='number')){
47
- if(isDate && rest.required === true ){
48
- rest.defaultValue = new Date();
49
- } else if(!isDate && isNonNullString(rest.appConfigDefaultValueKey)){
50
- rest.defaultValue = appConfig.get(rest.appConfigDefaultValueKey);
51
- }
52
- }
53
34
  return React.useMemo(()=>{
54
35
  customResponsiveProps = defaultObj(customResponsiveProps);
36
+ if(name){
37
+ rest.defaultValue = useDefaultValueFromData === false ? defaultValue : (name in data && data[name] !== undefined && data[name] !== null? data[name]: defaultValue);
38
+ if((type == 'selecttabledata' || type == 'datafile')){
39
+ rest._defaultValue = data[rest.name];
40
+ }
41
+ } else {
42
+ rest.defaultValue = defaultValue;
43
+ }
44
+ if(rest.defaultValue === null){
45
+ rest.defaultValue = undefined;
46
+ }
47
+ // les champs de type date par défaut qui sont requis, auront comme valeur par défaut la date actuelle s'il ne sont pas définies
48
+ if(rest.autoSetDefaultValue !== false && (!rest.defaultValue && typeof rest.defaultValue !=='boolean' && typeof rest.defaultValue !=='number')){
49
+ if(isDate && rest.required === true ){
50
+ rest.defaultValue = new Date();
51
+ } else if(!isDate && isNonNullString(rest.appConfigDefaultValueKey)){
52
+ rest.defaultValue = appConfig.get(rest.appConfigDefaultValueKey);
53
+ }
54
+ }
55
55
  const Component = getComponentFromType(jsType);
56
+ if(typeof onLoopField ==='function'){
57
+ onLoopField({...props,...fieldProp,formName,responsive,responsiveProps,...rest,type,jsType,primaryKey,name,isDate,index,disabled:disabled||archived,archivable})
58
+ }
56
59
  return <Component
57
60
  {...props}
58
61
  data = {data}
@@ -72,7 +75,7 @@ const FieldContentComponent = React.forwardRef(({field,data,index,fields,formNam
72
75
  responsive = {responsive}
73
76
  responsiveProps = {{...responsiveProps,...customResponsiveProps,style:[responsiveProps.style,customResponsiveProps.style]}}
74
77
  />
75
- },[rest.defaultValue,type,jsType,defaultValue,rest,windowWidth,backgroundColor,isFilter,name,!!responsive]);
78
+ },[type,jsType,defaultValue,rest,windowWidth,backgroundColor,isFilter,name,!!responsive]);
76
79
  });
77
80
 
78
81
  FieldContentComponent.displayName = "FieldContentComponent";
@@ -3,19 +3,16 @@ import Divider from "$ecomponents/Divider";
3
3
  import {isObj,isNonNullString,defaultStr,defaultObj} from "$utils";
4
4
  import {flattenStyle,Colors} from "$theme";
5
5
  import FieldContent from "./FieldContent";
6
- import stableHash from "stable-hash";
7
6
 
8
- export default function FieldsContent({fields,formName,disabled,archived,archivable,fieldProps,primaryKeyFields,responsiveProps,responsive,style,data,windowWidth}){
7
+ export default function FieldsContent({fields,formName,disabled,onLoopField,archived,archivable,fieldProps,primaryKeyFields,responsiveProps,isUpdate,responsive,style,data,windowWidth,...rest}){
8
+ if(!Object.size(fields,true)) return null;
9
9
  windowWidth = typeof windowWidth ==='number' && windowWidth > 100?windowWidth : undefined;
10
10
  primaryKeyFields = isObj(primaryKeyFields) ? primaryKeyFields : Array.isArray(primaryKeyFields) ? primaryKeyFields: [];
11
11
  const isPArray = Array.isArray(primaryKeyFields);
12
12
  const backgroundColor = flattenStyle(style)?.backgroundColor;
13
- const prevResponsive = React.usePrevious(responsive);
14
13
  return React.useMemo(()=>{
15
14
  const content = [];
16
15
  fieldProps = defaultObj(fieldProps);
17
- console.log("rendering fields contens alla ",fieldProps,fields,data,responsive,prevResponsive);
18
- //console.log("rendering form data ",formName,archived,backgroundColor,primaryKeyFields,responsive,responsiveProps)
19
16
  Object.map(fields,(field,index,i)=>{
20
17
  if(field === 'divider'){
21
18
  content.push(<Divider key = {index} style={theme.styles.w100}/>)
@@ -27,6 +24,7 @@ export default function FieldsContent({fields,formName,disabled,archived,archiva
27
24
  content.push(<FieldContent
28
25
  field = {field}
29
26
  index = {index}
27
+ onLoopField = {onLoopField}
30
28
  increment = {i}
31
29
  archivable={archivable}
32
30
  disabled = {disabled}
@@ -44,5 +42,5 @@ export default function FieldsContent({fields,formName,disabled,archived,archiva
44
42
  />)
45
43
  });
46
44
  return content;
47
- },[formName,archived,backgroundColor,archivable,primaryKeyFields,isPArray,disabled,fields,responsiveProps,responsive])
45
+ },[formName,archived,backgroundColor,data,archivable,primaryKeyFields,isPArray,disabled,isUpdate,fields,responsiveProps,responsive])
48
46
  }
@@ -1,8 +1,7 @@
1
1
  import {getAppBarActionsProps} from "./utils";
2
2
  import React, {Component as AppComponent} from "$react";
3
3
  import {isNonNullString,defaultStr,defaultNumber,defaultObj,extendObj,isObj,isFunction,defaultFunc,uniqid} from "$cutils";
4
- import {getForm,getFormField,Forms} from "../utils";
5
- import Divider from "$ecomponents/Divider";
4
+ import {getForm,getFormField} from "../utils";
6
5
  import Surface from "$ecomponents/Surface";
7
6
  import Form from "../Form";
8
7
  import theme,{flattenStyle} from "$theme";
@@ -62,6 +61,9 @@ export default class FormDataComponent extends AppComponent{
62
61
  onSave(args){
63
62
  return true;
64
63
  }
64
+ reset(args){
65
+ return null;
66
+ }
65
67
  getAppBarActionsProps(props){
66
68
  let {data,onCancel,perm,beforeSaveArgumentsMutator,beforeSave,actions,saveDataMutator,...rest} = (defaultObj(props,this.props));
67
69
  const onSave = typeof props.onSave ==='function'? props.onSave : this.props.onSave ;
@@ -179,26 +181,6 @@ export default class FormDataComponent extends AppComponent{
179
181
  isArchivable (){
180
182
  return false;
181
183
  }
182
- getFieldsContent = (formProps)=>{
183
- formProps = defaultObj(formProps);
184
- this.formDataPrimaryKeyFields = {};
185
- const data = isObj(formProps.data) ? formProps.data : typeof this.props.data =='object' && this.props.data ? this.props.data : {};
186
- return <FieldsContent
187
- {...formProps}
188
- fields = {defaultObj(formProps.fields,this.props.fields)}
189
- fieldProps = {defaultObj(formProps.fieldProps,this.props.fieldProps)}
190
- style = {flattenStyle(formProps.style)}
191
- data = {data}
192
- responsive = {typeof formProps.responsive =='boolean' ? formProps.responsive : this.props.responsive !== false ? true : false}
193
- responsiveProps = {extendObj({},this.props.responsiveProps,formProps.responsiveProps)}
194
- windowWidth = {defaultNumber(formProps.windowWidth,this.props.windowWidth) || undefined}
195
- primaryKeyFields = {this.formDataPrimaryKeyFields}
196
- formName = {this.getFormName()}
197
- disabled = {this.props.disabled}
198
- archived = {this.props.archived || data?.archived && true || false}
199
- archivable = {this.props.archivable || this.isArchivable()}
200
- />
201
- }
202
184
  getActions (){
203
185
  return renderActions(this.getAppBarActionsProps());
204
186
  }
@@ -301,14 +283,42 @@ export default class FormDataComponent extends AppComponent{
301
283
  containerProps = Object.assign({},containerProps);
302
284
  const cStyle = flattenStyle([styles.container,{backgroundColor:theme.surfaceBackgroundColor},containerProps.style]);
303
285
  formProps.style = flattenStyle([{backgroundColor:cStyle.backgroundColor},formProps.style]);
304
- formProps.fields = defaultObj(formProps.fields,fields);
305
- formProps.windowWidth = defaultNumber(formProps.windowWidth,windowWidth) || undefined;
286
+ data = isObj(formProps.data) ? formProps.data : isObj(data) ? data : {};
287
+ ///getting fields content
288
+ this.formDataPrimaryKeyFields = defaultObj(this.primaryKeyFields);
306
289
  const content = <Form
307
290
  {...formProps}
291
+ windowWidth = {defaultNumber(formProps.windowWidth,windowWidth) || undefined}
308
292
  name={this.getFormName()}
309
293
  onKeyEvent = {this.onKeyEvent.bind(this)}
294
+ data = {data}
310
295
  >
311
- {this.getFieldsContent(formProps)}
296
+ <FieldsContent
297
+ {...formProps}
298
+ fields = {defaultObj(formProps.fields,fields)}
299
+ fieldProps = {defaultObj(formProps.fieldProps,this.props.fieldProps)}
300
+ style = {flattenStyle(formProps.style)}
301
+ data = {data}
302
+ responsive = {typeof formProps.responsive =='boolean' ? formProps.responsive : this.props.responsive !== false ? true : false}
303
+ responsiveProps = {extendObj({},this.props.responsiveProps,formProps.responsiveProps)}
304
+ windowWidth = {defaultNumber(formProps.windowWidth,this.props.windowWidth) || undefined}
305
+ primaryKeyFields = {this.formDataPrimaryKeyFields}
306
+ formName = {this.getFormName()}
307
+ disabled = {this.props.disabled}
308
+ archived = {this.props.archived || data?.archived && true || false}
309
+ archivable = {this.props.archivable || this.isArchivable()}
310
+ onLoopField={(opts)=>{
311
+ this.formDataPrimaryKeyFields = defaultObj(this.formDataPrimaryKeyFields);
312
+ if(opts.primaryKey){
313
+ this.formDataPrimaryKeyFields[opts.name] = true;
314
+ } else {
315
+ delete this.formDataPrimaryKeyFields[opts.name];
316
+ }
317
+ if(typeof this.props.onLoopField ==='function'){
318
+ this.props.onLoopField(opts)
319
+ }
320
+ }}
321
+ />
312
322
  </Form>
313
323
  if(this.handleCustomRender()){
314
324
  return this._render({
@@ -318,7 +328,7 @@ export default class FormDataComponent extends AppComponent{
318
328
  });
319
329
  }
320
330
  if(typeof children ==='function'){
321
- this._render(children({
331
+ return this._render(children({
322
332
  header,
323
333
  context : this,
324
334
  content,
@@ -351,7 +361,8 @@ FormDataComponent.propTypes = {
351
361
  PropTypes.string,
352
362
  PropTypes.number,
353
363
  PropTypes.node,
354
- ])
364
+ ]),
365
+ onLoopField : PropTypes.func,//la fonction appelée lorsqu'on boucle sur un champ du form data
355
366
  }
356
367
 
357
368
  const styles = {
@@ -0,0 +1,20 @@
1
+ import {KeyboardAvoidingView,StyleSheet} from 'react-native';
2
+
3
+ export default function KeyboardAvoidingViewComponent({ children,...rest }){
4
+ return (
5
+ <KeyboardAvoidingView
6
+ behavior="padding"
7
+ keyboardVerticalOffset={80}
8
+ {...rest}
9
+ style = {[styles.wrapper,rest.style]}
10
+ >
11
+ {children}
12
+ </KeyboardAvoidingView>
13
+ );
14
+ };
15
+
16
+ const styles = StyleSheet.create({
17
+ wrapper: {
18
+ flex: 1,
19
+ },
20
+ });
@@ -1,21 +1,4 @@
1
- import {isIos} from "$cplatform";
2
- import {KeyboardAvoidingView,StyleSheet} from 'react-native';
3
1
 
4
- export default function KeyboardAvoidingViewComponent({ children,...rest }){
5
- return isIos() ? (
6
- <KeyboardAvoidingView
7
- style={styles.wrapper}
8
- behavior="padding"
9
- keyboardVerticalOffset={80}
10
- {...rest}
11
- >
12
- {children}
13
- </KeyboardAvoidingView>
14
- ) : children;
15
- };
16
-
17
- const styles = StyleSheet.create({
18
- wrapper: {
19
- flex: 1,
20
- },
21
- });
2
+ export default function KeyboardAvoidingViewComponent({ children}){
3
+ return children;
4
+ }
@@ -7,7 +7,6 @@ import { screenName } from "$escreens/Auth/utils";
7
7
  import Image from "$ecomponents/Image";
8
8
  import { StyleSheet,View,Pressable} from "react-native";
9
9
  import avatarProps from "$eauth/avatarProps";
10
- import Button from "$ecomponents/Button";
11
10
  import Label from "$ecomponents/Label";
12
11
  import Icon from "$ecomponents/Icon";
13
12
  import {navigate} from "$cnavigation";
@@ -17,6 +16,7 @@ import appConfig from "$capp/config";
17
16
  import Preloader from "$preloader";
18
17
  import {defaultNumber} from "$cutils";
19
18
  import Tooltip from "$ecomponents/Tooltip";
19
+ import {isMultiUsersAllowed} from "$cauth/utils/session";
20
20
  const UserProfileAvatarComponent = React.forwardRef(({drawerRef,chevronIconProps:customChevronIconProps,size,withLabel,...props},ref)=>{
21
21
  let u = defaultObj(Auth.getLoggedUser());
22
22
  const deviceNameRef = React.useRef(null);
@@ -77,7 +77,7 @@ const UserProfileAvatarComponent = React.forwardRef(({drawerRef,chevronIconProps
77
77
  });
78
78
  }
79
79
  },
80
- {
80
+ isMultiUsersAllowed() && {
81
81
  label : i18n.lang("logout",'Déconnexion'),
82
82
  icon : "logout",
83
83
  onPress : (a)=>{
@@ -77,7 +77,7 @@ export default class FormDataLayout extends FormDataActions {
77
77
  const appBarProps = this.getAppBarActionsProps(props);
78
78
  appBarProps.elevation = typeof appBarProps.elevation =='number'? appBarProps.elevation : 5;
79
79
  return <ScreenContainer testID={defaultStr(testID,'RN_FormDataLayout')} {...props} appBarProps={appBarProps}>
80
- {this.wrapRenderingContent(content)}
80
+ {this.wrapRenderingContent(content)}
81
81
  </ScreenContainer>
82
82
  }
83
83
  }
@@ -3,19 +3,34 @@
3
3
  // license that can be found in the LICENSE file.
4
4
 
5
5
  import Container from "$cauth/Container";
6
- import ScreenWithOrWithoutAuthContainer from "./ScreenWithOrWithoutAuthContainer";
6
+ import ScreenWithoutAuthContainer from "./ScreenWithoutAuthContainer";
7
7
  import ProfilAvatar from "$elayouts/ProfilAvatar";
8
+ import {defaultObj,defaultBool,defaultArray,defaultStr} from "$cutils";
9
+ import View from "$components/View";
10
+ import theme from "$theme";
8
11
 
9
- export default function MainScreenComponent(props){
10
- return <ScreenWithOrWithoutAuthContainer
11
- {...props}
12
- renderProfilAvatar = {(props)=>{
13
- return <ProfilAvatar withLabel = {false} {...props} />
14
- }}
15
- renderChildren = {({containerProps,children})=>{
16
- return <Container {...containerProps}>
17
- {children}
18
- </Container>
19
- }}
20
- />
12
+ export default function MainScreenComponent({profilAvatarProps,withDrawer,allowDrawer,profilAvatarContainerProps,withProfilAvatarOnAppBar:cWithPorilAvatarOnAppbar,authProps,authRequired,...props}){
13
+ authProps = Object.assign({},authProps),
14
+ profilAvatarContainerProps = defaultObj(profilAvatarContainerProps);
15
+ profilAvatarProps = defaultObj(profilAvatarProps);
16
+ authRequired = defaultBool(authProps.required,authRequired,false);
17
+ withDrawer = typeof withDrawer =='boolean'? withDrawer : authRequired;
18
+ if(allowDrawer === false){
19
+ withDrawer = false;
20
+ }
21
+ const withProfilAvatarOnAppBar = cWithPorilAvatarOnAppbar !== false && withDrawer && !theme.showProfilAvatarOnDrawer ? true : false;
22
+ if(authRequired === false){
23
+ props.withFab = false;
24
+ }
25
+ return <Container authProps={authProps} required={authRequired}>
26
+ <ScreenWithoutAuthContainer
27
+ {...props}
28
+ withDrawer={withDrawer}
29
+ allowDrawer={allowDrawer}
30
+ authRequired = {authRequired}
31
+ right = {withProfilAvatarOnAppBar && <View testID={testID+"_ProfilAvatar_Container"} {...profilAvatarContainerProps} style={[profilAvatarContainerProps.style,styles.profilAvatarContainer]} >
32
+ {<ProfilAvatar withLabel={false} {...profilAvatarProps}/>}
33
+ </View> || null}
34
+ />
35
+ </Container>
21
36
  }
@@ -1,17 +1,177 @@
1
- // Copyright 2022 @fto-consult/Boris Fouomene. All rights reserved.
2
- // Use of this source code is governed by a BSD-style
3
- // license that can be found in the LICENSE file.
1
+ import React from '$react';
2
+ import {StyleSheet} from 'react-native';
3
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
+ import PropTypes from "prop-types";
5
+ import {defaultObj,defaultStr,defaultNumber,defaultBool,uniqid} from "$cutils";
6
+ import View from "$ecomponents/View";
7
+ import { useNavigation} from '$cnavigation';
8
+ import Fab from "$layouts/Fab";
9
+ import APP from "$capp";
10
+ import AppBar,{createAppBarRef} from "$elayouts/AppBar";
11
+ import Portal from "$ecomponents/Portal";
12
+ import {Portal as RNPortal} from "react-native-paper";
13
+ import theme,{StyleProp} from "$theme";
14
+ import StatusBar from "$ecomponents/StatusBar";
15
+ import ScrollView from "$ecomponents/ScrollView";
4
16
 
5
- /***
6
- *le fait que l'utilisateur soit connecté où pas
7
- */
17
+ const getDefaultTitle = (nTitle,returnStr)=>{
18
+ let titleStr = React.getTextContent(nTitle);
19
+ if(!titleStr){
20
+ titleStr = APP.getName();
21
+ }
22
+ const dbLabel = "";
23
+ if(!titleStr.toLowerCase().contains(dbLabel.toLowerCase())){
24
+ titleStr += " ["+dbLabel+"]";
25
+ }
26
+ if(returnStr) return titleStr;
27
+ return typeof nTitle =='string' ? titleStr : nTitle;
28
+ }
8
29
 
9
- import ScreenWithOrWithoutAuthContainer from "./ScreenWithOrWithoutAuthContainer";
10
- export default function ScreenWithoutAuthContainer(props){
11
- return <ScreenWithOrWithoutAuthContainer
12
- {...props}
13
- renderChildren = {({children})=>{
14
- return children
15
- }}
16
- />
30
+ export default function MainScreenScreenWithoutAuthContainer(props) {
31
+ let {
32
+ children,
33
+ withScrollView = false,
34
+ withStatusBar = true,
35
+ style,
36
+ contentContainerStyle,
37
+ options,
38
+ backAction,
39
+ appBarProps,
40
+ elevation,
41
+ withFab,
42
+ appBar,
43
+ authRequired,
44
+ withDrawer,
45
+ allowDrawer,
46
+ title,
47
+ subtitle,
48
+ modal,
49
+ fabProps,
50
+ screenName,
51
+ containerProps,
52
+ testID,
53
+ right,
54
+ ...rest
55
+ } = props;
56
+ const insets = useSafeAreaInsets();
57
+ testID = defaultStr(testID,"RN_MainScreenScreenWithoutAuthContainer")
58
+ containerProps = defaultObj(containerProps);
59
+ const backgroundColor = theme.colors.background;
60
+ const containerStyle = [
61
+ styles.container,
62
+ {
63
+ backgroundColor,
64
+ paddingBottom: insets.bottom,
65
+ paddingLeft: insets.left,
66
+ paddingRight: insets.right,
67
+ },
68
+ ];
69
+ options = defaultObj(options);
70
+ appBarProps = defaultObj(appBarProps)
71
+ title = defaultVal(title,appBarProps.title);
72
+ subtitle = defaultVal(subtitle,appBarProps.subtitle);
73
+ const appBarRef = createAppBarRef();
74
+ const navigation = useNavigation();
75
+ fabProps = defaultObj(fabProps);
76
+ withDrawer = typeof withDrawer =='boolean'? withDrawer : authRequired;
77
+ if(allowDrawer === false){
78
+ withDrawer = false;
79
+ }
80
+
81
+
82
+ React.useEffect(() => {
83
+ if((title||subtitle) && navigation && navigation.setOptions){
84
+ const appName = APP.getName().toUpperCase();
85
+ subtitle = React.getTextContent(subtitle);
86
+ let screenTitle = getDefaultTitle(title,true);
87
+ if(subtitle){
88
+ screenTitle += " | "+subtitle;
89
+ }
90
+ if(!screenTitle.toUpperCase().contains(appName)){
91
+ screenTitle+=" | "+appName;
92
+ }
93
+ navigation.setOptions({
94
+ ...options,
95
+ appBarProps:{...options.appBarProps,...appBarProps,title,subtitle},
96
+ subtitle :subtitle,
97
+ title : screenTitle,
98
+ });
99
+ }
100
+ }, [title,subtitle]);
101
+ const fab = withFab ? <Fab
102
+ {...fabProps}
103
+ screenName={screenName}
104
+ /> : null;
105
+ const Wrapper = React.useMemo(()=>modal ? PortalCP : React.Fragment,[modal]);
106
+ const WrapperProps = modal? {screenName} : {};
107
+ const portalId = uniqid("screeen-container-"+screenName);
108
+ return <Wrapper {...WrapperProps}>
109
+ <View testID={testID} id={portalId} {...containerProps} style={[styles.container,{backgroundColor},modal && styles.modal,containerProps.style]}>
110
+ {withStatusBar !== false ? <StatusBar/> : null}
111
+ {appBar === false ? null : React.isValidElement(appBar)? state.AppBar : <AppBar
112
+ testID={testID+'_AppBar'} {...appBarProps}
113
+ backAction = {defaultVal(appBarProps.backAction,backAction)}
114
+ elevation={defaultNumber(appBarProps.elevation,elevation)}
115
+ withDrawer={withDrawer} options={options}
116
+ ref={appBarRef} title={title}
117
+ subtitle={subtitle}
118
+ right = {right}
119
+ />}
120
+ {withScrollView !== false ? (
121
+ <ScrollView
122
+ testID = {testID+'_ScreenContentScrollView'}
123
+ {...rest}
124
+ contentContainerStyle={[contentContainerStyle]}
125
+ style={[containerStyle,styles.container, style]}
126
+ >
127
+ {children}
128
+ {fab}
129
+ </ScrollView>
130
+ ) : (
131
+ <View testID={testID+'_ScreenContent'} {...rest} style={[containerStyle,styles.wrapper,styles.container, style]}>
132
+ {children}
133
+ {fab}
134
+ </View>
135
+ )}
136
+ </View>
137
+ </Wrapper>
138
+ }
139
+
140
+ const PortalCP = ({children})=>{
141
+ return <RNPortal>
142
+ {children}
143
+ </RNPortal>
144
+ }
145
+
146
+ const styles = StyleSheet.create({
147
+ container: {
148
+ flex: 1,
149
+ },
150
+ wrapper : {
151
+ flexDirection:'column',
152
+ /*flex : 1,
153
+ flexGrow : 1,
154
+ alignItems:'center'*/
155
+ },
156
+ modal : {
157
+ ...StyleSheet.absoluteFillObject,
158
+ top : 0,
159
+ left:0,
160
+ flex:1,
161
+ width : '100%',
162
+ height : '100%'
163
+ }
164
+ });
165
+
166
+ MainScreenScreenWithoutAuthContainer.propTypes = {
167
+ children: PropTypes.any,
168
+ withScrollView : PropTypes.bool,
169
+ style:StyleProp,
170
+ appBarProps : PropTypes.object,
171
+ elevation : PropTypes.number,
172
+ //appBar : PropTypes.bool,
173
+ contentContainerStyle : StyleProp,
174
+ withFab : PropTypes.bool,
175
+ withDrawer : PropTypes.bool,//si l'on doit afficher un drawer dans le contenu
176
+ fabProps : PropTypes.object,
17
177
  }
@@ -559,8 +559,9 @@ export default class TableDataScreenComponent extends FormDataScreen{
559
559
  }
560
560
  return;
561
561
  }
562
- reset (args,cb){
562
+ reset (args,...rest){
563
563
  if(!this._isMounted()) return;
564
+ super.reset(args,...rest)
564
565
  clearTimeout(this.timeoutCallback);
565
566
  this.showPreloader();
566
567
  this.timeoutCallback = setTimeout(()=>{
@@ -1,196 +0,0 @@
1
- import React from '$react';
2
- import {StyleSheet} from 'react-native';
3
- import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
- import PropTypes from "prop-types";
5
- import {defaultObj,defaultStr,defaultNumber,defaultBool,uniqid} from "$cutils";
6
- import View from "$ecomponents/View";
7
- import { useNavigation} from '$cnavigation';
8
- import Fab from "$layouts/Fab";
9
- import APP from "$capp";
10
- import AppBar,{createAppBarRef} from "$elayouts/AppBar";
11
- import Portal from "$ecomponents/Portal";
12
- import { FullWindowOverlay } from 'react-native-screens';
13
- import theme,{StyleProp} from "$theme";
14
- import StatusBar from "$ecomponents/StatusBar";
15
- import ScrollView from "$ecomponents/ScrollView";
16
- const getDefaultTitle = (nTitle,returnStr)=>{
17
- let titleStr = React.getTextContent(nTitle);
18
- if(!titleStr){
19
- titleStr = APP.getName();
20
- }
21
- const dbLabel = "";
22
- if(!titleStr.toLowerCase().contains(dbLabel.toLowerCase())){
23
- titleStr += " ["+dbLabel+"]";
24
- }
25
- if(returnStr) return titleStr;
26
- return typeof nTitle =='string' ? titleStr : nTitle;
27
- }
28
-
29
- export default function MainScreenScreenWithOrWithoutAuthContainer(props) {
30
- let {
31
- children,
32
- withScrollView = false,
33
- withStatusBar = true,
34
- style,
35
- contentContainerStyle,
36
- options,
37
- backAction,
38
- appBarProps,
39
- authProps,
40
- elevation,
41
- withFab,
42
- appBar,
43
- authRequired,
44
- withDrawer,
45
- allowDrawer,
46
- title,
47
- subtitle,
48
- modal,
49
- fabProps,
50
- screenName,
51
- containerProps,
52
- testID,
53
- profilAvatarProps,
54
- profilAvatarContainerProps,
55
- withProfilAvatarOnAppBar:cWithPorilAvatarOnAppbar,
56
- renderChildren,
57
- renderProfilAvatar,
58
- ...rest
59
- } = props;
60
- const insets = useSafeAreaInsets();
61
- testID = defaultStr(testID,"RN_MainScreenScreenWithOrWithoutAuthContainer")
62
- containerProps = defaultObj(containerProps);
63
- profilAvatarContainerProps = defaultObj(profilAvatarContainerProps);
64
- profilAvatarProps = defaultObj(profilAvatarProps);
65
- const backgroundColor = theme.colors.background;
66
- const containerStyle = [
67
- styles.container,
68
- {
69
- backgroundColor,
70
- paddingBottom: insets.bottom,
71
- paddingLeft: insets.left,
72
- paddingRight: insets.right,
73
- },
74
- ];
75
- options = defaultObj(options);
76
- appBarProps = defaultObj(appBarProps)
77
- title = defaultVal(title,appBarProps.title);
78
- subtitle = defaultVal(subtitle,appBarProps.subtitle);
79
- const appBarRef = createAppBarRef();
80
- const navigation = useNavigation();
81
- authProps = Object.assign({},authProps),
82
- fabProps = defaultObj(fabProps);
83
- authRequired = defaultBool(authProps.required,authRequired,false);
84
- withDrawer = typeof withDrawer =='boolean'? withDrawer : authRequired;
85
- if(allowDrawer === false){
86
- withDrawer = false;
87
- }
88
- if(authRequired === false){
89
- withFab = false;
90
- }
91
- const withProfilAvatarOnAppBar = cWithPorilAvatarOnAppbar !== false && withDrawer && !theme.showProfilAvatarOnDrawer ? true : false;
92
- React.useEffect(() => {
93
- if((title||subtitle) && navigation && navigation.setOptions){
94
- const appName = APP.getName().toUpperCase();
95
- subtitle = React.getTextContent(subtitle);
96
- let screenTitle = getDefaultTitle(title,true);
97
- if(subtitle){
98
- screenTitle += " | "+subtitle;
99
- }
100
- if(!screenTitle.toUpperCase().contains(appName)){
101
- screenTitle+=" | "+appName;
102
- }
103
- navigation.setOptions({
104
- ...options,
105
- appBarProps:{...options.appBarProps,...appBarProps,title,subtitle},
106
- subtitle :subtitle,
107
- title : screenTitle,
108
- });
109
- }
110
- }, [title,subtitle]);
111
- const Wrapper = modal ? PortalCP : React.Fragment;
112
- const WrapperProps = modal? {screenName} : {};
113
- const fab = withFab ? <Fab
114
- {...fabProps}
115
- screenName={screenName}
116
- /> : null;
117
- const profilAvatar = typeof renderProfilAvatar =='function'? renderProfilAvatar(profilAvatarProps) : null;
118
- const portalId = uniqid("screeen-container-"+screenName);
119
- return <Wrapper {...WrapperProps}>
120
- {renderChildren({
121
- containerProps : {
122
- ...authProps,
123
- required : authRequired,
124
- },
125
- children : <View testID={testID} id={portalId} {...containerProps} style={[styles.container,{backgroundColor},modal && styles.modal,containerProps.style]}>
126
- {withStatusBar !== false ? <StatusBar/> : null}
127
- {appBar === false ? null : React.isValidElement(appBar)? state.AppBar : <AppBar
128
- testID={testID+'_AppBar'} {...appBarProps}
129
- backAction = {defaultVal(appBarProps.backAction,backAction)}
130
- elevation={defaultNumber(appBarProps.elevation,elevation)}
131
- withDrawer={withDrawer} options={options}
132
- ref={appBarRef} title={title}
133
- subtitle={subtitle}
134
- right = {withProfilAvatarOnAppBar && <View testID={testID+"_ProfilAvatar_Container"} {...profilAvatarContainerProps} style={[profilAvatarContainerProps.style,styles.profilAvatarContainer]} >
135
- {React.isValidElement(profilAvatar) && profilAvatar || null}
136
- </View> || null}
137
- />}
138
- {withScrollView !== false ? (
139
- <ScrollView
140
- testID = {testID+'_ScreenContentScrollView'}
141
- {...rest}
142
- contentContainerStyle={[contentContainerStyle]}
143
- style={[containerStyle,styles.container, style]}
144
- >
145
- {children}
146
- {fab}
147
- </ScrollView>
148
- ) : (
149
- <View testID={testID+'_ScreenContent'} {...rest} style={[containerStyle,styles.wrapper,styles.container, style]}>
150
- {children}
151
- {fab}
152
- </View>
153
- )}
154
- </View>,
155
- })}
156
- </Wrapper>
157
- }
158
-
159
- const PortalCP = ({children,screenName})=>{
160
- return <Portal>
161
- {children}
162
- </Portal>
163
- }
164
-
165
- const styles = StyleSheet.create({
166
- container: {
167
- flex: 1,
168
- },
169
- wrapper : {
170
- flexDirection:'column',
171
- /*flex : 1,
172
- flexGrow : 1,
173
- alignItems:'center'*/
174
- },
175
- modal : {
176
- ...StyleSheet.absoluteFillObject,
177
- top : 0,
178
- left:0,
179
- flex:1,
180
- width : '100%',
181
- height : '100%'
182
- }
183
- });
184
-
185
- MainScreenScreenWithOrWithoutAuthContainer.propTypes = {
186
- children: PropTypes.any,
187
- withScrollView : PropTypes.bool,
188
- style:StyleProp,
189
- appBarProps : PropTypes.object,
190
- elevation : PropTypes.number,
191
- //appBar : PropTypes.bool,
192
- contentContainerStyle : StyleProp,
193
- withFab : PropTypes.bool,
194
- withDrawer : PropTypes.bool,//si l'on doit afficher un drawer dans le contenu
195
- fabProps : PropTypes.object,
196
- }