@fto-consult/expo-ui 5.8.11 → 5.9.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.
@@ -16,6 +16,29 @@ module.exports = (opts)=>{
16
16
  const cpath = fs.existsSync(euCommon)? path.resolve(euCommon,"babel.config.alias") : "@fto-consult/common/babel.config.alias";
17
17
  const r = require(`${cpath}`)(opts);
18
18
  const expo = path.resolve(expoUI,"src");
19
+
20
+ /**** package json */
21
+ const packagePath = path.resolve(base,"package.json");
22
+ const configPath = path.resolve(expo,"app.config.json");
23
+ if(fs.existsSync(packagePath)){
24
+ try {
25
+ const packageObj = require(`${packagePath}`);
26
+ if(typeof packageObj.name =="string"){
27
+ packageObj.name = packageObj.name.toUpperCase();
28
+ }
29
+ if(packageObj){
30
+ ["scripts","private","main","repository","keywords","bugs","dependencies","devDependencies"].map(v=>{
31
+ delete packageObj[v];
32
+ })
33
+ fs.writeFileSync(configPath,JSON.stringify(packageObj,null,"\t"));
34
+ }
35
+ } catch (e){
36
+ console.log(e," writing file sync on package JSON, file : $common/babel.config.alias")
37
+ }
38
+ }
39
+ if(fs.existsSync(configPath)){
40
+ r["$package.json"] = r["$packageJSON"] = configPath;
41
+ }
19
42
  r["$eauth"] = path.resolve(expo,"auth");
20
43
  r["$ecomponents"] = r["$expo-components"] = path.resolve(expo,"components");
21
44
  r["$etableLink"] = r["$eTableLink"] = path.resolve(r["$ecomponents"],"TableLink");
package/babel.config.js CHANGED
@@ -14,7 +14,6 @@ module.exports = function(api,opts) {
14
14
  inlineDovOptions.path ='./.env';
15
15
  }
16
16
  /*** par défaut, les variables d'environnements sont stockés dans le fichier .env situé à la racine du projet, référencée par la prop base */
17
-
18
17
  const alias = require("./babel.config.alias")(options);
19
18
  return {
20
19
  presets: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fto-consult/expo-ui",
3
- "version": "5.8.11",
3
+ "version": "5.9.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.6",
62
62
  "@expo/html-elements": "^0.2.0",
63
63
  "@expo/vector-icons": "^13.0.0",
64
- "@fto-consult/common": "^3.12.0",
64
+ "@fto-consult/common": "^3.13.16",
65
65
  "@gorhom/portal": "^1.0.14",
66
66
  "@react-native-async-storage/async-storage": "^1.17.11",
67
67
  "@react-native-community/datetimepicker": "^6.7.3",
package/src/App.js CHANGED
@@ -2,18 +2,11 @@ import '$session';
2
2
  import React from 'react';
3
3
  import {SWRConfig} from "$swr";
4
4
  import {defaultObj} from "$cutils";
5
- import {updateTheme,defaultTheme} from "$theme";
6
- import {Provider as PaperProvider } from 'react-native-paper';
7
5
  import Index from './index';
8
6
  import notify from "$notify";
9
7
  import { SafeAreaProvider } from 'react-native-safe-area-context';
10
- import { PreferencesContext } from './Preferences';
11
- import {AuthProvider} from '$cauth';
12
- import ErrorBoundary from "$ecomponents/ErrorBoundary";
13
8
  import {GestureHandlerRootView} from "react-native-gesture-handler";
14
- import StatusBar from "$ecomponents/StatusBar";
15
9
  import APP from "$app";
16
- import FontIcon from "$ecomponents/Icon/Font"
17
10
  import {isMobileNative} from "$cplatform";
18
11
  import {setDeviceIdRef} from "$capp";
19
12
  import appConfig from "$capp/config";
@@ -30,7 +23,7 @@ Object.map(Utils,(v,i)=>{
30
23
  window[i] = v;
31
24
  }
32
25
  });
33
- export default function getIndex({onMount,onUnmount,swrConfig,render,onRender,preferences:appPreferences,...rest}){
26
+ export default function getIndex({onMount,onUnmount,swrConfig,onRender,...rest}){
34
27
  const isScreenFocusedRef = React.useRef(true);
35
28
  ///garde pour chaque écran sa date de dernière activité
36
29
  const screensRef = React.useRef({});//la liste des écrans actifs
@@ -97,19 +90,7 @@ export default function getIndex({onMount,onUnmount,swrConfig,render,onRender,pr
97
90
  }
98
91
  }
99
92
  },[])
100
- const [theme,setTheme] = React.useState(updateTheme(defaultTheme));
101
- const updatePreferenceTheme = (customTheme,persist)=>{
102
- setTheme(updateTheme(customTheme));
103
- };
104
- const forceRender = React.useForceRender();
105
- const pref = typeof appPreferences =='function'? appPreferences({setTheme,forceRender,updateTheme:updatePreferenceTheme}) : appPreferences;
106
- const preferences = React.useMemo(()=>({
107
- updateTheme:updatePreferenceTheme,
108
- theme,
109
- ...defaultObj(pref),
110
- }),[theme,pref]);
111
- const child = <Index {...rest} theme={theme}/>;
112
- const content = typeof render == 'function'? render({children:child,appConfig,config:appConfig}) : child;
93
+
113
94
  return (
114
95
  <SWRConfig
115
96
  value={{
@@ -160,25 +141,9 @@ export default function getIndex({onMount,onUnmount,swrConfig,render,onRender,pr
160
141
  }}
161
142
  >
162
143
  <GestureHandlerRootView style={{ flex: 1 }}>
163
- <PaperProvider
164
- theme={theme}
165
- settings={{
166
- icon: (props) => {
167
- return <FontIcon {...props}/>
168
- },
169
- }}
170
- >
171
- <SafeAreaProvider>
172
- <AuthProvider>
173
- <ErrorBoundary>
174
- <StatusBar/>
175
- <PreferencesContext.Provider value={preferences}>
176
- {React.isValidElement(content) && content || child}
177
- </PreferencesContext.Provider>
178
- </ErrorBoundary>
179
- </AuthProvider>
180
- </SafeAreaProvider>
181
- </PaperProvider>
144
+ <SafeAreaProvider>
145
+ <Index {...rest}/>
146
+ </SafeAreaProvider>
182
147
  </GestureHandlerRootView>
183
148
  </SWRConfig>
184
149
  );
@@ -934,19 +934,22 @@ export default class CommonDatagridComponent extends AppComponent {
934
934
  })
935
935
  if(size === 1 && canMakePhoneCall === true && canMakeCall()){
936
936
  const rowKey = Object.keys(this.selectedRows)[0], rowData = defaultObj(this.selectedRows[rowKey]);
937
- let callProps = typeof makePhoneCallProps == 'function'? makePhoneCallProps(rowData,rowKey) : makePhoneCallProps;
938
- callProps = defaultObj(callProps);
939
- r.push({
940
- text : defaultStr(callProps.text,callProps.label,'Appeler'),
941
- icon : defaultStr(callProps.icon,'phone'),
942
- flat : true,
943
- onPress : ()=>{
944
- return makePhoneCall(
945
- rowData,
946
- callProps
947
- );
948
- }
949
- })
937
+ const table = defaultStr(this.props.table,this.props.tableName).trim();
938
+ let callProps = typeof makePhoneCallProps == 'function'? makePhoneCallProps({rowData,rowKey,table,tableName:table,data:rowData,key:rowKey,context:this,props:this.props}) : makePhoneCallProps;
939
+ if(callProps !== false){
940
+ callProps = defaultObj(callProps);
941
+ r.push({
942
+ text : defaultStr(callProps.text,callProps.label,'Appeler'),
943
+ icon : defaultStr(callProps.icon,'phone'),
944
+ flat : true,
945
+ onPress : ()=>{
946
+ return makePhoneCall(
947
+ rowData,
948
+ callProps
949
+ );
950
+ }
951
+ })
952
+ }
950
953
  }
951
954
  if(isObj(this.props.columns) && size ===1){
952
955
  r.push({
@@ -65,7 +65,7 @@ export const getSWROptions = ()=>{
65
65
  }
66
66
  }
67
67
 
68
-
68
+ const isValidMakePhoneCallProps = p=> isObj(p) && Object.size(p,true) || typeof p ==='function';
69
69
  /****la fonction fetcher doit toujours retourner :
70
70
  * 1. la liste des éléments fetchés dans la props data
71
71
  * 2. le nombre total d'éléments de la liste obtenue en escluant les clause limit et offset correspondant à la même requête
@@ -118,7 +118,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
118
118
  delete sort.column;
119
119
  }
120
120
  canMakePhoneCall = defaultBool(canMakePhoneCall,table.canMakePhoneCall);
121
- makePhoneCallProps = defaultObj(makePhoneCallProps,rest.makePhoneCallProps,table.makePhoneCallProps);
121
+ makePhoneCallProps = isValidMakePhoneCallProps(makePhoneCallProps) && makePhoneCallProps || isValidMakePhoneCallProps(rest.makePhoneCallProps) && rest.makePhoneCallProps || isValidMakePhoneCallProps(table.makePhoneCallProps) && table.makePhoneCallProps || {};
122
122
  const isExportable = !!Auth.isTableDataAllowed({table:tableName,action:'export'});
123
123
  rest.exportable = isExportable;
124
124
  rowKey = defaultStr(rowKey,table.rowKey,table.primaryKeyColumnName);
@@ -1,7 +1,7 @@
1
1
  /* @flow */
2
2
  /*** fork of https://www.npmjs.com/package/react-native-animated-splash-screen */
3
3
  import PropTypes from "prop-types"
4
- import * as React from "react"
4
+ import React from "$react"
5
5
  import {Animated, StyleSheet } from "react-native";
6
6
  import View from "$ecomponents/View";
7
7
  import {isNativeMobile} from "$cplatform";
@@ -19,167 +19,136 @@ import styles, {
19
19
  const isNative = isNativeMobile();
20
20
  const Component = isNative? Animated.View : View;
21
21
 
22
- class AnimatedSplash extends React.Component {
23
- static defaultProps = {
24
- isLoaded: false,
25
- }
26
-
27
- state = {
22
+ const SplashScreenComponent = ({isLoaded,children , duration, delay,logoWidth,logoHeight,backgroundColor,imageBackgroundSource,imageBackgroundResizeMode,
23
+ testID,
24
+ disableAppScale,
25
+ disableImageBackgroundAnimation,preload})=>{
26
+ const [state,setState] = React.useState({
28
27
  animationDone: false,
29
28
  loadingProgress: new Animated.Value(0)
30
- }
31
-
32
- componentDidUpdate(prevProps) {
33
- const { isLoaded , duration, delay } = this.props
34
- const { loadingProgress } = this.state
35
-
36
- if (isLoaded && !prevProps.isLoaded) {
37
- if(!isNativeMobile()){
38
- this.setState({animationDone:true});
39
- } else {
40
- Animated.timing(loadingProgress, {
41
- toValue: 100,
42
- duration: duration || 1000,
43
- delay: delay || 0,
44
- useNativeDriver: true,
45
- }).start(() => {
46
- this.setState({
47
- animationDone: true,
48
- })
49
- })
50
- }
51
- }
52
- }
53
-
54
- renderChildren() {
55
- const { children, preload, isLoaded } = this.props
56
- if (preload || preload == null) {
57
- return children
29
+ });
30
+ const { loadingProgress, animationDone } = state;
31
+ const prevIsLoaded = React.usePrevious(isLoaded);
32
+ React.useEffect(()=>{
33
+ if(prevIsLoaded == isLoaded || !isLoaded) return;
34
+ if(!isNativeMobile()){
35
+ setState({...state,animationDone:true});
58
36
  } else {
59
- if (isLoaded) {
60
- return children
61
- }
37
+ Animated.timing(loadingProgress, {
38
+ toValue: 100,
39
+ duration: duration || 1000,
40
+ delay: delay || 0,
41
+ useNativeDriver: true,
42
+ }).start(() => {
43
+ setState({
44
+ ...state,
45
+ animationDone: true,
46
+ })
47
+ })
62
48
  }
63
-
64
- return null
49
+ },[isLoaded]);
50
+ testID = defaultStr(testID,"RN_SplashscreenComponent")
51
+ logoWidth = defaultDecimal(logoWidth,150);
52
+ logoHeight = defaultDecimal(logoHeight,250);
53
+ const opacityClearToVisible = {
54
+ opacity: loadingProgress.interpolate({
55
+ inputRange: [0, 15, 30],
56
+ outputRange: [0, 0, 1],
57
+ extrapolate: "clamp",
58
+ }),
59
+ }
60
+ const imageScale = {
61
+ transform: [
62
+ {
63
+ scale: loadingProgress.interpolate({
64
+ inputRange: [0, 10, 100],
65
+ outputRange: [1, 1, 65],
66
+ }),
67
+ },
68
+ ],
65
69
  }
66
70
 
67
- render() {
68
- const { loadingProgress, animationDone } = this.state
69
- let {
70
- logoImage,
71
- logoWidth,
72
- logoHeight,
73
- backgroundColor,
74
- imageBackgroundSource,
75
- imageBackgroundResizeMode,
76
- testID,
77
- disableAppScale,
78
- disableImageBackgroundAnimation,
79
- } = this.props
80
- testID = defaultStr(testID,"RN_SplashscreenComponent")
81
- logoWidth = defaultDecimal(logoWidth,150);
82
- logoHeight = defaultDecimal(logoHeight,250);
83
- const opacityClearToVisible = {
84
- opacity: loadingProgress.interpolate({
85
- inputRange: [0, 15, 30],
86
- outputRange: [0, 0, 1],
87
- extrapolate: "clamp",
88
- }),
89
- }
90
-
91
- const imageScale = {
92
- transform: [
93
- {
94
- scale: loadingProgress.interpolate({
95
- inputRange: [0, 10, 100],
96
- outputRange: [1, 1, 65],
97
- }),
98
- },
99
- ],
100
- }
101
-
102
- const logoScale = {
103
- transform: [
104
- {
105
- scale: loadingProgress.interpolate({
106
- inputRange: [0, 10, 100],
107
- outputRange: [1, 0.8, 10],
108
- }),
109
- },
110
- ],
111
- }
71
+ const logoScale = {
72
+ transform: [
73
+ {
74
+ scale: loadingProgress.interpolate({
75
+ inputRange: [0, 10, 100],
76
+ outputRange: [1, 0.8, 10],
77
+ }),
78
+ },
79
+ ],
80
+ }
112
81
 
113
- const logoOpacity = {
114
- opacity: loadingProgress.interpolate({
115
- inputRange: [0, 20, 100],
116
- outputRange: [1, 0, 0],
117
- extrapolate: "clamp",
118
- }),
119
- }
82
+ const logoOpacity = {
83
+ opacity: loadingProgress.interpolate({
84
+ inputRange: [0, 20, 100],
85
+ outputRange: [1, 0, 0],
86
+ extrapolate: "clamp",
87
+ }),
88
+ }
120
89
 
121
- const appScale = {
122
- transform: [
123
- {
124
- scale: loadingProgress.interpolate({
125
- inputRange: [0, 7, 100],
126
- outputRange: [1.1, 1.05, 1],
127
- }),
128
- },
129
- ],
130
- }
131
-
132
- return (
133
- <View style={[styles.container]} testID={testID} nativeID={testID}>
134
- {!animationDone && <View style={StyleSheet.absoluteFill} testID={testID+"_Animation"}/>}
135
- <View style={styles.containerGlue}>
136
- {!animationDone && (
137
- <Animated.View
138
- style={_staticBackground(logoOpacity, backgroundColor)}
139
- testID={testID+"_AnimationDone"}
140
- />
141
- )}
142
- {(animationDone || isNative) && <Component style={[!disableAppScale && appScale, opacityClearToVisible, styles.flex]}>
143
- {this.renderChildren()}
144
- </Component>}
145
- {!animationDone && (
146
- <Animated.Image
147
- testID={testID+"AnimateImage"}
148
- resizeMode={imageBackgroundResizeMode || "cover"}
149
- source={imageBackgroundSource}
150
- style={[disableImageBackgroundAnimation && _staticBackground(
151
- logoOpacity,
152
- backgroundColor
153
- ), disableImageBackgroundAnimation && _dynamicImageBackground(
154
- imageScale,
155
- logoOpacity,
156
- backgroundColor
157
- )]}
158
- />
159
- )}
160
- {!animationDone && (
161
- <View testID={testID+"_LogoContainer"} style={[StyleSheet.absoluteFill, styles.logoStyle]}>
162
- {(
163
- <Animated.View
164
- testID={testID+"_Logo"}
165
- style={_dynamicCustomComponentStyle(
166
- logoScale,
167
- logoOpacity,
168
- logoWidth,
169
- logoHeight
170
- )}>
171
- {<LogoProgress/>}
172
- </Animated.View>
173
- )}
174
- </View>
175
- )}
176
- </View>
177
- </View>
178
- )
90
+ const appScale = {
91
+ transform: [
92
+ {
93
+ scale: loadingProgress.interpolate({
94
+ inputRange: [0, 7, 100],
95
+ outputRange: [1.1, 1.05, 1],
96
+ }),
97
+ },
98
+ ],
179
99
  }
100
+ const child = (animationDone && isLoaded)? React.isValidElement(children) && children : null;
101
+ return (
102
+ <View style={[styles.container]} testID={testID} nativeID={testID}>
103
+ {!animationDone && <View style={StyleSheet.absoluteFill} testID={testID+"_Animation"}/>}
104
+ <View style={styles.containerGlue}>
105
+ {!animationDone && (
106
+ <Animated.View
107
+ style={_staticBackground(logoOpacity, backgroundColor)}
108
+ testID={testID+"_AnimationDone"}
109
+ />
110
+ )}
111
+ {(animationDone || isNative) && <Component style={[!disableAppScale && appScale, opacityClearToVisible, styles.flex]}>
112
+ {child}
113
+ </Component>}
114
+ {!animationDone && (
115
+ <Animated.Image
116
+ testID={testID+"AnimateImage"}
117
+ resizeMode={imageBackgroundResizeMode || "cover"}
118
+ source={imageBackgroundSource}
119
+ style={[disableImageBackgroundAnimation && _staticBackground(
120
+ logoOpacity,
121
+ backgroundColor
122
+ ), disableImageBackgroundAnimation && _dynamicImageBackground(
123
+ imageScale,
124
+ logoOpacity,
125
+ backgroundColor
126
+ )]}
127
+ />
128
+ )}
129
+ {!animationDone && (
130
+ <View testID={testID+"_LogoContainer"} style={[StyleSheet.absoluteFill, styles.logoStyle]}>
131
+ {(
132
+ <Animated.View
133
+ testID={testID+"_Logo"}
134
+ style={_dynamicCustomComponentStyle(
135
+ logoScale,
136
+ logoOpacity,
137
+ logoWidth,
138
+ logoHeight
139
+ )}>
140
+ {<LogoProgress/>}
141
+ </Animated.View>
142
+ )}
143
+ </View>
144
+ )}
145
+ </View>
146
+ </View>
147
+ )
180
148
  }
181
149
 
182
- AnimatedSplash.propTypes = {
150
+
151
+ SplashScreenComponent.propTypes = {
183
152
  preload: PropTypes.bool,
184
153
  logoWidth: PropTypes.number,
185
154
  children: PropTypes.element,
@@ -197,4 +166,5 @@ AnimatedSplash.propTypes = {
197
166
  delay: PropTypes.number,
198
167
  }
199
168
 
200
- export default AnimatedSplash
169
+ SplashScreenComponent.displayName = "SplashScreenComponent";
170
+ export default SplashScreenComponent;
package/src/index.js CHANGED
@@ -31,6 +31,13 @@ import {PortalProvider,PortalHost } from '$ecomponents/Portal';
31
31
  import ErrorBoundaryProvider from "$ecomponents/ErrorBoundary/Provider";
32
32
  import notify, {notificationRef} from "$notify";
33
33
  import DropdownAlert from '$ecomponents/Dialog/DropdownAlert';
34
+ import {AuthProvider} from '$cauth';
35
+ import { PreferencesContext } from './Preferences';
36
+ import ErrorBoundary from "$ecomponents/ErrorBoundary";
37
+ import {updateTheme,defaultTheme} from "$theme";
38
+ import StatusBar from "$ecomponents/StatusBar";
39
+ import {Provider as PaperProvider } from 'react-native-paper';
40
+ import FontIcon from "$ecomponents/Icon/Font";
34
41
 
35
42
  let MAX_BACK_COUNT = 1;
36
43
  let countBack = 0;
@@ -48,13 +55,13 @@ const NAVIGATION_PERSISTENCE_KEY = 'NAVIGATION_STATE';
48
55
  * initialRouteName : la route initiale par défaut
49
56
  * getStartedRouteName : la route par défaut de getStarted lorsque l'application est en mode getStarted, c'est à dire lorsque la fonction init renvoie une erreur (reject)
50
57
  */
51
- function App({init:initApp,initialRouteName:appInitialRouteName,getStartedRouteName}) {
58
+ function App({init:initApp,initialRouteName:appInitialRouteName,render,preferences:appPreferences,getStartedRouteName}) {
52
59
  AppStateService.init();
53
60
  const [initialState, setInitialState] = React.useState(undefined);
54
61
  const appReadyRef = React.useRef(true);
55
62
  const [state,setState] = React.useState({
56
63
  isLoading : true,
57
- isInitialized:true,
64
+ isInitialized:false,
58
65
  });
59
66
  React.useEffect(() => {
60
67
  const loadResources = ()=>{
@@ -220,35 +227,67 @@ function App({init:initApp,initialRouteName:appInitialRouteName,getStartedRouteN
220
227
  }
221
228
  },[isInitialized]);
222
229
  const hasGetStarted = state.hasGetStarted !== false? true : false;
230
+
231
+ const [theme,setTheme] = React.useState(updateTheme(defaultTheme));
232
+ const updatePreferenceTheme = (customTheme,persist)=>{
233
+ setTheme(updateTheme(customTheme));
234
+ };
235
+ const forceRender = React.useForceRender();
236
+ const pref = typeof appPreferences =='function'? appPreferences({setTheme,forceRender,updateTheme:updatePreferenceTheme}) : appPreferences;
237
+ const preferences = React.useMemo(()=>({
238
+ updateTheme:updatePreferenceTheme,
239
+ theme,
240
+ ...defaultObj(pref),
241
+ }),[theme,pref]);
242
+ const isLoaded = !isLoading;
243
+ const child = isLoaded ? <NavigationContainer
244
+ ref={navigationRef}
245
+ initialState={initialState}
246
+ onStateChange={(state) =>{
247
+ setSession(NAVIGATION_PERSISTENCE_KEY,decycle(state),false);
248
+ }
249
+ }
250
+ >
251
+ <PortalProvider>
252
+ <Portal.Host>
253
+ <PreloaderProvider/>
254
+ <DialogProvider responsive/>
255
+ <AlertProvider SimpleSelect={SimpleSelect}/>
256
+ <FormDataDialogProvider/>
257
+ <BottomSheetProvider/>
258
+ <DropdownAlert ref={notificationRef}/>
259
+ <ErrorBoundaryProvider/>
260
+ <Navigation
261
+ initialRouteName = {defaultStr(hasGetStarted ? appInitialRouteName : getStartedRouteName,"Home")}
262
+ state = {state}
263
+ hasGetStarted = {hasGetStarted}
264
+ isInitialized = {!isLoading}
265
+ onGetStart = {(e)=>{
266
+ setState({...state,hasGetStarted:true})
267
+ }}
268
+ />
269
+ </Portal.Host>
270
+ </PortalProvider>
271
+ </NavigationContainer> : null;
272
+ const content = isLoaded ? typeof render == 'function'? render({children:child,appConfig,config:appConfig}) : child : null;
223
273
  return (<SplashScreen isLoaded={!isLoading}>
224
- <NavigationContainer
225
- ref={navigationRef}
226
- initialState={initialState}
227
- onStateChange={(state) =>{
228
- setSession(NAVIGATION_PERSISTENCE_KEY,decycle(state),false);
229
- }
230
- }
231
- >
232
- <PortalProvider>
233
- <Portal.Host>
234
- <PreloaderProvider/>
235
- <DialogProvider responsive/>
236
- <AlertProvider SimpleSelect={SimpleSelect}/>
237
- <FormDataDialogProvider/>
238
- <BottomSheetProvider/>
239
- <DropdownAlert ref={notificationRef}/>
240
- <ErrorBoundaryProvider/>
241
- <Navigation
242
- initialRouteName = {defaultStr(hasGetStarted ? appInitialRouteName : getStartedRouteName,"Home")}
243
- state = {state}
244
- hasGetStarted = {hasGetStarted}
245
- onGetStart = {(e)=>{
246
- setState({...state,hasGetStarted:true})
247
- }}
248
- />
249
- </Portal.Host>
250
- </PortalProvider>
251
- </NavigationContainer>
274
+ <AuthProvider>
275
+ <PaperProvider
276
+ theme={theme}
277
+ settings={{
278
+ icon: (props) => {
279
+ return <FontIcon {...props}/>
280
+ },
281
+ }}
282
+ >
283
+ <ErrorBoundary>
284
+ <StatusBar/>
285
+ <PreferencesContext.Provider value={preferences}>
286
+ {React.isValidElement(content) && content || child}
287
+ </PreferencesContext.Provider>
288
+ </ErrorBoundary>
289
+ </PaperProvider>
290
+ </AuthProvider>
252
291
  </SplashScreen>);
253
292
  }
254
293
 
@@ -54,7 +54,7 @@ export default function DatabaseStatisticScreen ({withScreen,fetchDataProps,tabl
54
54
  if(!content.length) {
55
55
  return null;
56
56
  }
57
- content = <Component {...containerProps} style={[containerProps.style,theme.styles.mr1,theme.styles.ml1]}>
57
+ content = <Component {...containerProps} style={[containerProps.style,theme.styles.mr1,theme.styles.pv1,theme.styles.ml1]}>
58
58
  {content}
59
59
  </Component>;
60
60
  return withScreen !== false ? <Screen containerProps={{style:[{flexGrow:0,flex:0}]}} withScrollView title={defaultVal(customTitle,title)} {...props}>{content}</Screen> : content;
@@ -755,11 +755,14 @@ export default class TableDataScreenComponent extends FormDataScreen{
755
755
  getMakePhoneCallProps (){
756
756
  const table = this.table;
757
757
  const makePhoneCallProps = defaultVal(this.makePhoneCallProps,table.makePhoneCallProps);
758
- return defaultObj(typeof makePhoneCallProps === 'function' ? makePhoneCallProps(this.getCurrentData()) : makePhoneCallProps);
758
+ const rowData = this.getCurrentData();
759
+ const mP = typeof makePhoneCallProps === 'function' ? makePhoneCallProps({rowData,data:rowData,isTableData:true,props:this.props,context:this,table,tableName:this.table}) : makePhoneCallProps;
760
+ return mP !== false ? defaultObj(mP) : null;
759
761
  }
760
762
  makePhoneCall(data){
761
- if(!this.canMakePhoneCall() || !canMakePhoneCall()) return false;
762
- makePCall(defaultObj(data || this.getCurrentData()),this.getMakePhoneCallProps());
763
+ const mP = this.getMakePhoneCallProps();
764
+ if(!this.canMakePhoneCall() || !canMakePhoneCall() || !isObj(mP)) return false;
765
+ makePCall(defaultObj(data || this.getCurrentData()),mP);
763
766
  return false;
764
767
  }
765
768
 
@@ -103,8 +103,11 @@ export function renderActions({context,isUpdate,newElementLabel,makePhoneCallPr
103
103
  rest = defaultObj(rest);
104
104
  newElementLabel = defaultStr(newElementLabel,"Nouveau");
105
105
  let permsObj = checkPermsActions.call(self,{...defaultObj(perms),isUpdate})
106
- makePhoneCallProps = defaultObj(makePhoneCallProps);
106
+ makePhoneCallProps = typeof makePhoneCallProps ==='function'? makePhoneCallProps({data,rowData:data,context:{},isTableDataActions:true,table,tableName:table}): makePhoneCallProps;
107
107
  self.permsObj = permsObj;
108
+ if(makePhoneCallProps !== false){
109
+ makePhoneCallProps = defaultObj(makePhoneCallProps);
110
+ }
108
111
  let save = (!readOnly && !permsObj.canSave || (saveAction === false))? null: {
109
112
  text :hasManyData? 'Modifier': textSave,
110
113
  title :hasManyData? 'Modifier': textSave,
@@ -197,7 +200,7 @@ export function renderActions({context,isUpdate,newElementLabel,makePhoneCallPr
197
200
  flat : true,
198
201
  onPress : createCallback({context:self,action:'new',callback:onPressToCreateNew})
199
202
  } : null,
200
- makePhoneCall : (canMakePhoneCall && isUpdate)?{
203
+ makePhoneCall : (canMakePhoneCall && isUpdate && isObj(makePhoneCallProps))?{
201
204
  text : defaultStr(makePhoneCallProps.text,makePhoneCallProps.label,'Appeler'),
202
205
  isAction : true,
203
206
  icon : defaultStr(makePhoneCallProps.icon,'phone'),
@@ -1,7 +1,7 @@
1
1
  import showConfirm from "$components/Dialog/confirm";
2
- import notify from "$components/Dialog/notify";
2
+ import notify from "$notify";
3
3
  import {defaultArray,arrayValueExists,defaultStr,uniqid} from "$cutils";
4
- import userDbName from "$database/data/tables/users/dbName";
4
+ import userDbName from "$database/tables/users/dbName";
5
5
  import Auth from "$auth";
6
6
  import getData from "$database/getData";
7
7
  import getDB from "$database/getDB";