@fto-consult/expo-ui 6.26.2 → 6.26.4
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 +2 -2
- package/src/components/Datagrid/Accordion/Filters.js +36 -38
- package/src/components/Datagrid/Common/Common.js +5 -2
- package/src/components/Datagrid/SWRDatagrid.js +22 -53
- package/src/components/Dialog/AppBarDialog.js +2 -1
- package/src/components/ErrorBoundary/ErrorMessage.js +3 -2
- package/src/components/ErrorBoundary/Provider.js +4 -3
- package/src/components/ErrorBoundary/index.js +1 -0
- package/src/components/Filter/index.js +1 -0
- package/src/components/Form/Fields/Field.js +3 -2
- package/src/components/Form/Fields/IdField.js +38 -28
- package/src/components/Form/FormData/componentsTypes.js +11 -4
- package/src/components/Icon/Icon.js +1 -1
- package/src/components/List/Virtuoso/index.js +1 -2
- package/src/components/Logo/Progress.js +9 -5
- package/src/components/Menu/Menu.js +113 -97
- package/src/components/Portal/Portal.js +88 -0
- package/src/components/Portal/PortalHost.js +31 -0
- package/src/components/Portal/PortalProvider.js +31 -0
- package/src/components/Portal/constants.js +15 -0
- package/src/components/Portal/context.js +10 -0
- package/src/components/Portal/hooks.js +75 -0
- package/src/components/Portal/index.js +11 -3
- package/src/components/Portal/index.old.js +4 -0
- package/src/components/Portal/reducer.js +92 -0
- package/src/components/Portal/usePortalState.js +19 -0
- package/src/components/Preloader/index.js +1 -1
- package/src/components/ScrollView/index.js +1 -0
- package/src/components/SplashScreen/index.js +2 -2
- package/src/components/StatusBar/Component/index.web.js +0 -1
- package/src/components/Table/EmptyPlaceholder/index.js +41 -0
- package/src/components/Table/EmptyPlaceholder/index.native.js +3 -0
- package/src/components/Table/hooks.js +1 -1
- package/src/components/Table/index.js +13 -7
- package/src/components/TextField/index.js +1 -0
- package/src/context/Provider.js +7 -0
- package/src/context/hooks.js +1 -2
- package/src/context/query.js +92 -0
- package/src/index.js +34 -41
- package/src/navigation/index.js +2 -1
- package/src/screens/Help/openLibraries.js +1 -1
- package/src/components/Icon/IconButton.js +0 -155
|
@@ -98,7 +98,7 @@ const SplashScreenComponent = ({isLoaded,children , duration, delay,logoWidth,lo
|
|
|
98
98
|
],
|
|
99
99
|
}
|
|
100
100
|
const child = (animationDone && isLoaded)? React.isValidElement(children) && children : null;
|
|
101
|
-
if(animationDone) return child;
|
|
101
|
+
if(animationDone && isLoaded) return child;
|
|
102
102
|
return <View style={[styles.container]} testID={testID} id={testID}>
|
|
103
103
|
{!animationDone ? <View style={StyleSheet.absoluteFill} testID={testID+"_Animation"}/> : null}
|
|
104
104
|
<View style={styles.containerGlue} testID={testID+"_ContainerGlue"}>
|
|
@@ -108,7 +108,7 @@ const SplashScreenComponent = ({isLoaded,children , duration, delay,logoWidth,lo
|
|
|
108
108
|
testID={testID+"_AnimationDone"}
|
|
109
109
|
/>
|
|
110
110
|
)}
|
|
111
|
-
{(animationDone || isNative) && child}
|
|
111
|
+
{false && (animationDone || isNative) && child}
|
|
112
112
|
{!animationDone && (
|
|
113
113
|
<View testID={testID+"_LogoContainer"} style={[StyleSheet.absoluteFill, styles.logoStyle]}>
|
|
114
114
|
{(
|
|
@@ -53,7 +53,6 @@ export default function StatusBarComponent(props){
|
|
|
53
53
|
}
|
|
54
54
|
},[]);
|
|
55
55
|
return null;
|
|
56
|
-
return <StatusBar {...styles} {...props}></StatusBar>
|
|
57
56
|
}
|
|
58
57
|
const updateThemeName = (theme)=>{
|
|
59
58
|
if(typeof document ==="undefined" || !document || !isDOMElement(document.body)) return null;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {useEffect} from "react";
|
|
2
|
+
import { StyleSheet } from "react-native";
|
|
3
|
+
import View from "$ecomponents/View";
|
|
4
|
+
import {defaultStr,defaultNumber,uniqid,classNames} from "$cutils";
|
|
5
|
+
import { useWindowDimensions } from "react-native";
|
|
6
|
+
import {useTable} from "../hooks";
|
|
7
|
+
|
|
8
|
+
export default function EmptyPlaceholderComponent({testID,content}){
|
|
9
|
+
testID = defaultStr(testID,"RN_VirtuosoTableEmptyPlaceholder");
|
|
10
|
+
const {id : tableId,visibleColsNames} = useTable();
|
|
11
|
+
const id = `${tableId}-empty-placeholder`;
|
|
12
|
+
const listID = `${tableId}-list`;
|
|
13
|
+
const clx = "virtuoso-table-empty-placehoder";
|
|
14
|
+
const {width:dimW} = useWindowDimensions();
|
|
15
|
+
useEffect(()=>{
|
|
16
|
+
const list = document.querySelector(`#${listID}`),content = document.querySelector(`#${id}-content`);
|
|
17
|
+
if(!list || !content || !list.offsetWidth) return;
|
|
18
|
+
const width = list.offsetWidth || list.clientWidth;
|
|
19
|
+
content.style.width = `${width}px`;
|
|
20
|
+
},[dimW]);
|
|
21
|
+
return <tbody id={`${id}-tbody`} data-test-id={`${testID}-tbody`} className={`${clx}-tbody`} style={wStyle}>
|
|
22
|
+
<tr id={`${id}-tr`} data-test-id={`${testID}-tr`} className={`${clx}-tr`} style={wStyle}>
|
|
23
|
+
<td colSpan={visibleColsNames.length} id={`${id}-td`} width={"100%"} height={"100%"} data-test-id={`${testID}-td`} style={wStyle}>
|
|
24
|
+
<View testID={testID} id={`${id}-content`} style={styles.content}>{content}</View>
|
|
25
|
+
</td>
|
|
26
|
+
</tr>
|
|
27
|
+
</tbody>
|
|
28
|
+
}
|
|
29
|
+
const wStyle = {
|
|
30
|
+
width : "100%",
|
|
31
|
+
height : "100%",
|
|
32
|
+
position : "relative"
|
|
33
|
+
}
|
|
34
|
+
const styles = StyleSheet.create({
|
|
35
|
+
content : {
|
|
36
|
+
alignItems:"center",
|
|
37
|
+
justifyContent : "center",
|
|
38
|
+
height : "100%",
|
|
39
|
+
width : "100%",
|
|
40
|
+
},
|
|
41
|
+
})
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import View from "$ecomponents/View";
|
|
2
|
-
import {defaultObj,defaultStr,debounce,defaultNumber,isObj,defaultVal} from "$cutils";
|
|
2
|
+
import {defaultObj,defaultStr,debounce,defaultNumber,uniqid,isObj,defaultVal} from "$cutils";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import React from "$react";
|
|
5
5
|
import { StyleSheet,View as RNView,ScrollView,Dimensions} from "react-native";
|
|
@@ -15,6 +15,7 @@ import {useIsRowSelected} from "$ecomponents/Datagrid/hooks";
|
|
|
15
15
|
import {getRowStyle} from "$ecomponents/Datagrid/utils";
|
|
16
16
|
import ScrollNative from "./ScrollNative";
|
|
17
17
|
import VirtuosoTableComponent from "./VirtuosoTable";
|
|
18
|
+
import EmptyPlaceholder from "./EmptyPlaceholder";
|
|
18
19
|
export {styles};
|
|
19
20
|
|
|
20
21
|
const isSCrollingRef = React.createRef();
|
|
@@ -124,9 +125,9 @@ const TableComponent = React.forwardRef(({containerProps,listContainerStyle,onRe
|
|
|
124
125
|
}
|
|
125
126
|
}
|
|
126
127
|
}
|
|
127
|
-
const onComponentRender = (
|
|
128
|
+
const onComponentRender = (...args)=>{
|
|
128
129
|
if(onRender){
|
|
129
|
-
onRender(
|
|
130
|
+
onRender(...args);
|
|
130
131
|
}
|
|
131
132
|
//au paravant il était possible de faire scroller le composant Table lorsque les données sont raffraichies, ce qui n'avait pas un bon impact sur le rendu de la table de données
|
|
132
133
|
if(false && itemsChanged){
|
|
@@ -257,6 +258,9 @@ const TableComponent = React.forwardRef(({containerProps,listContainerStyle,onRe
|
|
|
257
258
|
return <TableRowComponent {...props} style={[getRowStyle(args),props.style]}/>
|
|
258
259
|
},
|
|
259
260
|
Table: VirtuosoTableComponent,
|
|
261
|
+
EmptyPlaceholder : (props)=>{
|
|
262
|
+
return <EmptyPlaceholder testID={testID+"_VirtuosoEmptyPlaceholder"} {...props} content={emptyContent}/>
|
|
263
|
+
}
|
|
260
264
|
}}
|
|
261
265
|
/>
|
|
262
266
|
{isNative ? <AbsoluteScrollView
|
|
@@ -334,20 +338,22 @@ TableComponent.popTypes = {
|
|
|
334
338
|
|
|
335
339
|
TableComponent.displayName = "TableComponent";
|
|
336
340
|
|
|
337
|
-
const TableComponentProvider = React.forwardRef(({children,renderCell,testID,withDatagridContext,getRowKey,filter,data,...props},ref)=>{
|
|
341
|
+
const TableComponentProvider = React.forwardRef(({children,id,renderCell,testID,withDatagridContext,getRowKey,filter,data,...props},ref)=>{
|
|
338
342
|
testID = props.testID = defaultStr(testID,"RN_TableComponent");
|
|
339
|
-
const
|
|
343
|
+
const idRef = React.useRef(defaultStr(id,uniqid("virtuoso-table-list-id")));
|
|
344
|
+
id = idRef.current;
|
|
345
|
+
const prepatedColumns = usePrepareColumns({...props,id});
|
|
340
346
|
const keyExtractor = typeof getRowKey =='function'? getRowKey : React.getKey;
|
|
341
347
|
const items = React.useMemo(()=>{
|
|
342
348
|
filter = typeof filter =='function'? filter : x=>true;
|
|
343
349
|
return data.filter((i,...rest)=>isObj(i) && !!filter(i,...rest));
|
|
344
350
|
},[data]);
|
|
345
351
|
const getItem = (index)=>items[index]||null;
|
|
346
|
-
return <TableContext.Provider value={{...props,...prepatedColumns,getItem,getRowByIndex:getItem,testID,data,withDatagridContext,keyExtractor,
|
|
352
|
+
return <TableContext.Provider value={{...props,...prepatedColumns,id,getItem,getRowByIndex:getItem,testID,data,withDatagridContext,keyExtractor,
|
|
347
353
|
renderCell,
|
|
348
354
|
items
|
|
349
355
|
}}>
|
|
350
|
-
<TableComponent {...props} ref={ref}/>
|
|
356
|
+
<TableComponent {...props} id={id} ref={ref}/>
|
|
351
357
|
</TableContext.Provider>
|
|
352
358
|
});
|
|
353
359
|
TableComponentProvider.displayName = "TableComponentProvider";
|
|
@@ -424,6 +424,7 @@ const TextFieldComponent = React.forwardRef((componentProps,inputRef)=>{
|
|
|
424
424
|
{valueToCopy?<Icon
|
|
425
425
|
{...iconProps}
|
|
426
426
|
title = {"Copier la valeur ["+valueToCopy+"] dans le presse papier"}
|
|
427
|
+
style = {[iconProps.style,{pointerEvents:"auto"}]}
|
|
427
428
|
icon = {COPY_ICON}
|
|
428
429
|
onPress = {(e)=>{
|
|
429
430
|
/*if(selectFieldToCopy){
|
package/src/context/Provider.js
CHANGED
|
@@ -85,6 +85,13 @@ const Provider = ({children,getTableData,navigation,components,convertFiltersToS
|
|
|
85
85
|
get customCSS(){
|
|
86
86
|
const prevCSS = defaultStr(typeof customCSS ==='function'? customCSS(theme) : customCSS);
|
|
87
87
|
return `
|
|
88
|
+
#root {
|
|
89
|
+
overflow:hidden!important;
|
|
90
|
+
width : 100%!important;
|
|
91
|
+
height : 100%important;
|
|
92
|
+
left : 0!important;
|
|
93
|
+
top : 0!important;
|
|
94
|
+
}
|
|
88
95
|
.virtuoso-table-component,
|
|
89
96
|
.virtuoso-table-component th,
|
|
90
97
|
.virtuoso-table-component tr,
|
package/src/context/hooks.js
CHANGED
|
@@ -5,7 +5,6 @@ import useStableMemo from "$react/useStableMemo";
|
|
|
5
5
|
import { useWindowDimensions } from "$cdimensions";
|
|
6
6
|
import {isObj,isNonNullString} from "$cutils";
|
|
7
7
|
import { StyleSheet } from "react-native";
|
|
8
|
-
|
|
9
8
|
import { createContext,useContext as useReactContext } from "react";
|
|
10
9
|
|
|
11
10
|
export const ExpoUIContext = createContext(null);
|
|
@@ -63,4 +62,4 @@ export function useMediaQueryUpdateStyle({useCurrentMedia,target,mediaQueryUpdat
|
|
|
63
62
|
if(isObj(nStyle) || Array.isArray(nStyle)) return StyleSheet.flatten([props.style,nStyle]);
|
|
64
63
|
return StyleSheet.flatten(props.style)||{};
|
|
65
64
|
},[handleProps,useCurrentMedia,dimensions,props.style]);
|
|
66
|
-
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import {isNonNullString,isObj,extendObj,defaultObj,defaultStr} from "$utils";
|
|
2
|
+
import { useQuery as useRQuery, useMutation as RQUseMutation, useQueryClient } from "@tanstack/react-query";
|
|
3
|
+
import { getFetcherOptions as apiGetFetcherOptions } from '$capi';
|
|
4
|
+
|
|
5
|
+
export const RETRY_OPTIONS = { cacheTime: 2000,refetchInterval:5000};
|
|
6
|
+
|
|
7
|
+
export const RETRY_LIST_OPTIONS = {cacheTime:5000,refetchInterval:20000};
|
|
8
|
+
|
|
9
|
+
const isValidNetworkMode = (nMode)=>isNonNullString(nMode) && ['online','always','offlineFirst'].includes(nMode.toLowerCase().trim());
|
|
10
|
+
const isValidRetryDelay = (retryDelay) => typeof retryDelay =='number' || typeof retryDelay ==='function'? true : false;
|
|
11
|
+
|
|
12
|
+
const queries403Cached = {};
|
|
13
|
+
|
|
14
|
+
/***** override of useQuery
|
|
15
|
+
@see : https://tanstack.com/query/v4/docs/react/guides/migrating-to-react-query-4
|
|
16
|
+
@see : https://tanstack.com/query/v4/docs/react/reference/useQuery for useQuery options
|
|
17
|
+
@param {boolean} handle403, pour la prise en compte du 403
|
|
18
|
+
@param {Array} key, array of key string, The query key to use for this query.The query key will be hashed into a stable hash. See Query Keys for more information. The query will automatically update when this key changes (as long as enabled is not set to false).
|
|
19
|
+
@param {function} queryFn, query function (context: QueryFunctionContext) => Promise<TData>
|
|
20
|
+
@param {boolean} enabled Set this to false to disable this query from automatically running.
|
|
21
|
+
@param {string} networkMode 'online' | 'always' | 'offlineFirst
|
|
22
|
+
@param {boolean| number | (failureCount: number, error: TError) => boolean} retry If false, failed queries will not retry by default.If true, failed queries will retry infinitely. If set to a number, e.g. 3, failed queries will retry until the failed query count meets that number.
|
|
23
|
+
@param {boolean} retryOnMount If set to false, the query will not be retried on mount if it contains an error. Defaults to true.
|
|
24
|
+
@param {number | (retryAttempt: number, error: TError) => number} retryDelay This function receives a retryAttempt integer and the actual Error and returns the delay to apply before he next attempt in milliseconds. A function like attempt => Math.min(attempt > 1 ? 2 ** attempt * 1000 : 1000, 30 * 1000) applies exponential backoff., A function like attempt => attempt * 1000 applies linear backoff.
|
|
25
|
+
*/
|
|
26
|
+
export const useQuery = (key,queryFn,enabled,networkMode,retry,retryOnMount,retryDelay,...args)=>{
|
|
27
|
+
const options = isObj(key)? Object.assign({},key) : isNonNullString(key)? {queryKey:key.split(",")} : Array.isArray(key)? {queryKey:key} : {};
|
|
28
|
+
key = isNonNullString(key)? key.split(",") : Array.isArray(key)? key : [];
|
|
29
|
+
options.queryKey = Array.isArray(options.queryKey) && options.queryKey.length && options.queryKey || key;
|
|
30
|
+
options.queryFn = typeof queryFn =='function' ? queryFn : typeof options.queryFn =='function'? options.queryFn : undefined;
|
|
31
|
+
options.enabled = typeof enabled === "boolean" ? enabled : typeof options.enabled =='boolean' ? options.enabled : true;
|
|
32
|
+
options.networkMode = isValidNetworkMode(networkMode) ? networkMode.toLowerCase().trim() : isValidNetworkMode(options.networkMode) ? options.networkMode.toLowerCase().trim() : "online";
|
|
33
|
+
options.retry = typeof retry =='boolean' || typeof retry ==='number' ? retry : typeof options.retry ==='boolean' || typeof options.retry =='number' ? options.retry : undefined;
|
|
34
|
+
options.retryOnMount = typeof retryOnMount ==='boolean'? retryOnMount : typeof options.retryOnMount =='boolean' ? options.retryOnMount : undefined;
|
|
35
|
+
options.retryDelay = isValidRetryDelay(retryDelay)? retryDelay : isValidRetryDelay(options.retryDelay) ? options.retryDelay : undefined;
|
|
36
|
+
[queryFn,enabled,networkMode,retry,retryOnMount,retryDelay].map((a)=>{
|
|
37
|
+
isObj(a) && extendObj(true,options,a);
|
|
38
|
+
});
|
|
39
|
+
args.map((a)=>{
|
|
40
|
+
isObj(a) && extendObj(true,options,a);
|
|
41
|
+
});
|
|
42
|
+
options.enabled = !options.queryKey?.length ? false : options.enabled;
|
|
43
|
+
//if not enabled, we have to disabled retry option
|
|
44
|
+
options.retry = !options.enabled ? false : options.retry;
|
|
45
|
+
const {onError} = options;
|
|
46
|
+
const keyString = key.join(",");
|
|
47
|
+
if(keyString && queries403Cached[keyString]){
|
|
48
|
+
options.retry = false;
|
|
49
|
+
}
|
|
50
|
+
const {handle403} = options;
|
|
51
|
+
delete options.handle403;
|
|
52
|
+
options.onError = (e,...args)=>{
|
|
53
|
+
if(handle403){
|
|
54
|
+
const {response} = isObj(e)? e : {};
|
|
55
|
+
if(isObj(response) && response.status === 403){
|
|
56
|
+
keyString ? queries403Cached[keyString] = true : null;
|
|
57
|
+
setTimeout(()=>{
|
|
58
|
+
keyString && delete queries403Cached[keyString];
|
|
59
|
+
},100);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if(typeof onError ==='function' && (onError(e,options) === false)) return;
|
|
63
|
+
}
|
|
64
|
+
//const r = !options.enabled ? console.error("unable to get query for options",options) : null;
|
|
65
|
+
return useRQuery(options);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/****
|
|
69
|
+
@see : https://tanstack.com/query/v4/docs/react/reference/useMutation
|
|
70
|
+
*/
|
|
71
|
+
export const useMutation = (mutationFn,cacheTime,mutationKey,...args)=>{
|
|
72
|
+
const options = isObj(mutationFn)? Object.assign({},mutationFn) : typeof(mutationFn) =='function'? {mutationFn} : {};
|
|
73
|
+
mutationFn = typeof mutationFn ==='function' ? mutationFn : undefined;
|
|
74
|
+
mutationFn = mutationFn || typeof options.mutationFn == 'function' ? options.mutationFn : undefined;
|
|
75
|
+
options.cacheTime = typeof cacheTime =='number' ? cacheTime : typeof options.cacheTime =='number'? options.cacheTime : undefined;
|
|
76
|
+
options.mutationKey = isNonNullString(mutationKey) && mutationKey || isNonNullString(options.mutationKey) ? options.mutationKey : undefined;
|
|
77
|
+
[cacheTime,mutationKey].map((a)=>{
|
|
78
|
+
isObj(a) && extendObj(true,options,a);
|
|
79
|
+
});
|
|
80
|
+
args.map((a)=>{
|
|
81
|
+
isObj(a) && extendObj(true,options,a);
|
|
82
|
+
});
|
|
83
|
+
options.mutationFn = async (params,...rest) => {
|
|
84
|
+
return await mutationFn(params,...rest);
|
|
85
|
+
}
|
|
86
|
+
return RQUseMutation(options);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
export const getFetcherOptions = (path,opts)=>{
|
|
91
|
+
return apiGetFetcherOptions(path,opts);
|
|
92
|
+
}
|
package/src/index.js
CHANGED
|
@@ -28,7 +28,7 @@ import SimpleSelect from '$ecomponents/SimpleSelect';
|
|
|
28
28
|
import {Provider as AlertProvider} from '$ecomponents/Dialog/confirm/Alert';
|
|
29
29
|
import { DialogProvider as FormDataDialogProvider } from '$eform/FormData';
|
|
30
30
|
import {Portal } from 'react-native-paper';
|
|
31
|
-
import {PortalProvider} from '$ecomponents/Portal';
|
|
31
|
+
import {PortalProvider,CustomPortal} from '$ecomponents/Portal';
|
|
32
32
|
import ErrorBoundaryProvider from "$ecomponents/ErrorBoundary/Provider";
|
|
33
33
|
import notify, {notificationRef} from "$notify";
|
|
34
34
|
import DropdownAlert from '$ecomponents/Dialog/DropdownAlert';
|
|
@@ -40,9 +40,6 @@ import StatusBar from "$ecomponents/StatusBar";
|
|
|
40
40
|
import {Provider as PaperProvider } from 'react-native-paper';
|
|
41
41
|
import FontIcon from "$ecomponents/Icon/Font";
|
|
42
42
|
import useContext from "$econtext/hooks";
|
|
43
|
-
import {GestureHandlerRootView} from "react-native-gesture-handler";
|
|
44
|
-
import KeyboardAvoidingViewComponent from '$ecomponents/KeyboardAvoidingView';
|
|
45
|
-
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
46
43
|
export * from "./context";
|
|
47
44
|
|
|
48
45
|
let MAX_BACK_COUNT = 1;
|
|
@@ -256,59 +253,55 @@ function App({init:initApp,initialRouteName:appInitialRouteName,render,onMount})
|
|
|
256
253
|
onMountRef.current = true;
|
|
257
254
|
}
|
|
258
255
|
},[isLoaded])
|
|
259
|
-
const child = isLoaded ? <
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
256
|
+
const child = isLoaded ? <NavigationContainer
|
|
257
|
+
ref={navigationRef}
|
|
258
|
+
initialState={initialState}
|
|
259
|
+
onStateChange={(state) =>{
|
|
260
|
+
setSession(NAVIGATION_PERSISTENCE_KEY,decycle(state),false);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
>
|
|
264
|
+
<Navigation
|
|
265
|
+
initialRouteName = {defaultStr(hasGetStarted ? appInitialRouteName : getStartedRouteName,"Home")}
|
|
266
|
+
state = {state}
|
|
267
|
+
hasGetStarted = {hasGetStarted}
|
|
268
|
+
isInitialized = {isInitialized}
|
|
269
|
+
onGetStart = {(e)=>{
|
|
270
|
+
setState({...state,hasGetStarted:true})
|
|
271
|
+
}}
|
|
272
|
+
/>
|
|
273
|
+
</NavigationContainer> : null;
|
|
268
274
|
const content = isLoaded ? typeof render == 'function'? render({children:child,appConfig,config:appConfig}) : child : null;
|
|
269
275
|
return <AuthProvider>
|
|
270
|
-
|
|
271
|
-
ref={navigationRef}
|
|
272
|
-
initialState={initialState}
|
|
273
|
-
onStateChange={(state) =>{
|
|
274
|
-
if(!isLoaded) return;
|
|
275
|
-
setSession(NAVIGATION_PERSISTENCE_KEY,decycle(state),false);
|
|
276
|
-
}}
|
|
277
|
-
>
|
|
278
|
-
<PaperProvider
|
|
276
|
+
<PaperProvider
|
|
279
277
|
theme={theme}
|
|
280
278
|
settings={{
|
|
281
279
|
icon: (props) => {
|
|
282
280
|
return <FontIcon {...props}/>
|
|
283
281
|
},
|
|
284
282
|
}}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
283
|
+
>
|
|
284
|
+
<PortalProvider>
|
|
285
|
+
<ErrorBoundaryProvider/>
|
|
288
286
|
<PreloaderProvider/>
|
|
289
|
-
<DialogProvider responsive/>
|
|
287
|
+
<DialogProvider responsive testID={"RN_MainAppDialogProvider"}/>
|
|
290
288
|
<AlertProvider SimpleSelect={SimpleSelect}/>
|
|
291
289
|
<FormDataDialogProvider/>
|
|
292
290
|
<BottomSheetProvider/>
|
|
293
291
|
<DropdownAlert ref={notificationRef}/>
|
|
294
|
-
<
|
|
295
|
-
|
|
296
|
-
|
|
292
|
+
<Portal.Host testID="RN_NativePaperPortalHost">
|
|
293
|
+
<ErrorBoundary>
|
|
294
|
+
<StatusBar/>
|
|
297
295
|
<SplashScreen isLoaded={isLoaded}>
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
{React.isValidElement(content) && content || child}
|
|
302
|
-
</PreferencesContext.Provider>
|
|
303
|
-
</ErrorBoundary>
|
|
296
|
+
<PreferencesContext.Provider value={preferences}>
|
|
297
|
+
{React.isValidElement(content) && content || child}
|
|
298
|
+
</PreferencesContext.Provider>
|
|
304
299
|
</SplashScreen>
|
|
305
|
-
</
|
|
306
|
-
</
|
|
307
|
-
</
|
|
308
|
-
</PortalProvider>
|
|
300
|
+
</ErrorBoundary>
|
|
301
|
+
</Portal.Host>
|
|
302
|
+
</PortalProvider>
|
|
309
303
|
</PaperProvider>
|
|
310
|
-
|
|
311
|
-
</AuthProvider>
|
|
304
|
+
</AuthProvider>;
|
|
312
305
|
}
|
|
313
306
|
|
|
314
307
|
export default App;
|
package/src/navigation/index.js
CHANGED
|
@@ -15,7 +15,8 @@ export * from "./utils";
|
|
|
15
15
|
* lorsque hasGetStarted est à false, celle-ci rend l'écran Start permettant de rendre le contenu GetStarted
|
|
16
16
|
*/
|
|
17
17
|
export default function NavigationComponent (props){
|
|
18
|
-
let {state,hasGetStarted,onGetStart,initialRouteName,...rest} = props;
|
|
18
|
+
let {state,hasGetStarted,isLoading,onGetStart,initialRouteName,...rest} = props;
|
|
19
|
+
if(isLoading) return null;
|
|
19
20
|
const {navigation:{screens}} = useContext();
|
|
20
21
|
const allScreens = initScreens({Factory:Stack,screens,ModalFactory:Stack,filter:({name})=>{
|
|
21
22
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = {"@fto-consult/expo-ui":{"name":"@fto-consult/expo-ui","version":"6.
|
|
1
|
+
module.exports = {"@fto-consult/expo-ui":{"name":"@fto-consult/expo-ui","version":"6.26.3","repository":{"type":"git","url":"git+https://github.com/borispipo/expo-ui.git"},"homepage":"https://github.com/borispipo/expo-ui#readme"},"@emotion/native":{"version":"11.11.0","url":"https://emotion.sh","license":"MIT"},"@emotion/react":{"version":"11.11.1","url":"https://github.com/emotion-js/emotion/tree/main/packages/react","license":"MIT"},"@expo/html-elements":{"version":"0.5.1","url":"https://github.com/expo/expo/tree/main/packages/html-elements","license":"MIT"},"@expo/metro-config":{"version":"0.10.7","url":"https://github.com/expo/expo.git","license":"MIT"},"@expo/vector-icons":{"version":"13.0.0","url":"https://expo.github.io/vector-icons","license":"MIT"},"@expo/webpack-config":{"version":"18.1.2","url":"https://github.com/expo/expo-cli.git","license":"MIT"},"@faker-js/faker":{"version":"8.0.2","url":"https://github.com/faker-js/faker.git","license":"MIT"},"@fto-consult/common":{"version":"3.29.0","url":"https://github.com/borispipo/common#readme","license":"ISC"},"@gorhom/portal":{"version":"1.0.14","url":"https://github.com/gorhom/react-native-portal#readme","license":"MIT"},"@pchmn/expo-material3-theme":{"version":"1.3.1","url":"https://github.com/pchmn/expo-material3-theme#readme","license":"MIT"},"@react-native-async-storage/async-storage":{"version":"1.18.2","url":"https://github.com/react-native-async-storage/async-storage#readme","license":"MIT"},"@react-native-community/datetimepicker":{"version":"7.2.0","url":"https://github.com/react-native-community/datetimepicker#readme","license":"MIT"},"@react-native-community/netinfo":{"version":"9.3.10","url":"https://github.com/react-native-netinfo/react-native-netinfo#readme","license":"MIT"},"@react-native/assets-registry":{"version":"0.72.0","url":"git@github.com:facebook/react-native.git","license":"MIT"},"@react-navigation/native":{"version":"6.1.7","url":"https://reactnavigation.org","license":"MIT"},"@react-navigation/native-stack":{"version":"6.9.13","url":"https://github.com/software-mansion/react-native-screens#readme","license":"MIT"},"@shopify/flash-list":{"version":"1.4.3","url":"https://shopify.github.io/flash-list/","license":"MIT"},"apexcharts":{"version":"3.41.1","url":"https://apexcharts.com","license":"MIT"},"babel-plugin-inline-dotenv":{"version":"1.7.0","url":"https://github.com/brysgo/babel-plugin-inline-dotenv#readme","license":"ISC"},"babel-plugin-module-resolver":{"version":"5.0.0","url":"https://github.com/tleunen/babel-plugin-module-resolver.git","license":"MIT"},"expo":{"version":"49.0.7","url":"https://github.com/expo/expo/tree/main/packages/expo","license":"MIT"},"expo-camera":{"version":"13.4.2","url":"https://docs.expo.dev/versions/latest/sdk/camera/","license":"MIT"},"expo-clipboard":{"version":"4.3.1","url":"https://docs.expo.dev/versions/latest/sdk/clipboard","license":"MIT"},"expo-font":{"version":"11.4.0","url":"https://docs.expo.dev/versions/latest/sdk/font/","license":"MIT"},"expo-image-picker":{"version":"14.3.2","url":"https://docs.expo.dev/versions/latest/sdk/imagepicker/","license":"MIT"},"expo-linking":{"version":"5.0.2","url":"https://docs.expo.dev/versions/latest/sdk/linking","license":"MIT"},"expo-sqlite":{"version":"11.3.2","url":"https://docs.expo.dev/versions/latest/sdk/sqlite/","license":"MIT"},"expo-status-bar":{"version":"1.6.0","url":"https://docs.expo.dev/versions/latest/sdk/status-bar/","license":"MIT"},"expo-system-ui":{"version":"2.4.0","url":"https://docs.expo.dev/versions/latest/sdk/system-ui","license":"MIT"},"expo-web-browser":{"version":"12.3.2","url":"https://docs.expo.dev/versions/latest/sdk/webbrowser/","license":"MIT"},"file-saver":{"version":"2.0.5","url":"https://github.com/eligrey/FileSaver.js#readme","license":"MIT"},"fs-extra":{"version":"11.1.1","url":"https://github.com/jprichardson/node-fs-extra","license":"MIT"},"google-libphonenumber":{"version":"3.2.33","url":"https://ruimarinho.github.io/google-libphonenumber/","license":"(MIT AND Apache-2.0)"},"htmlparser2-without-node-native":{"version":"3.9.2","url":"git://github.com/fb55/htmlparser2.git","license":"MIT"},"pdfmake":{"version":"0.2.7","url":"http://pdfmake.org","license":"MIT"},"process":{"version":"0.11.10","url":"git://github.com/shtylman/node-process.git","license":"MIT"},"prop-types":{"version":"15.8.1","url":"https://facebook.github.io/react/","license":"MIT"},"react":{"version":"18.2.0","url":"https://reactjs.org/","license":"MIT"},"react-content-loader":{"version":"6.2.1","url":"https://github.com/danilowoz/react-content-loader","license":"MIT"},"react-dom":{"version":"18.2.0","url":"https://reactjs.org/","license":"MIT"},"react-native":{"version":"0.72.3","license":"MIT"},"react-native-big-list":{"version":"1.6.1","url":"https://marcocesarato.github.io/react-native-big-list-docs/","license":"GPL-3.0-or-later"},"react-native-blob-util":{"version":"0.18.6","url":"https://github.com/RonRadtke/react-native-blob-util","license":"MIT"},"react-native-gesture-handler":{"version":"2.12.1","url":"https://github.com/software-mansion/react-native-gesture-handler#readme","license":"MIT"},"react-native-iphone-x-helper":{"version":"1.3.1","url":"https://github.com/ptelad/react-native-iphone-x-helper#readme","license":"MIT"},"react-native-mime-types":{"version":"2.4.0","license":"MIT"},"react-native-paper":{"version":"5.10.1","url":"https://callstack.github.io/react-native-paper","license":"MIT"},"react-native-paper-dates":{"version":"0.18.14","url":"https://github.com/web-ridge/react-native-paper-dates#readme","license":"MIT"},"react-native-reanimated":{"version":"3.3.0","url":"https://github.com/software-mansion/react-native-reanimated#readme","license":"MIT"},"react-native-safe-area-context":{"version":"4.6.3","url":"https://github.com/th3rdwave/react-native-safe-area-context#readme","license":"MIT"},"react-native-screens":{"version":"3.22.1","url":"https://github.com/software-mansion/react-native-screens#readme","license":"MIT"},"react-native-svg":{"version":"13.9.0","url":"https://github.com/react-native-community/react-native-svg","license":"MIT"},"react-native-web":{"version":"0.19.7","url":"git://github.com/necolas/react-native-web.git","license":"MIT"},"react-native-webview":{"version":"13.2.2","url":"https://github.com/react-native-webview/react-native-webview#readme","license":"MIT"},"react-virtuoso":{"version":"4.5.0","url":"https://virtuoso.dev/","license":"MIT"},"sharp-cli":{"version":"4.1.1","url":"https://github.com/vseventer/sharp-cli","license":"MIT"},"tippy.js":{"version":"6.3.7","url":"https://atomiks.github.io/tippyjs/","license":"MIT"},"uninstall":{"version":"0.0.0","license":"MIT"},"websql":{"version":"2.0.3","url":"git://github.com/nolanlawson/node-websql.git","license":"Apache-2.0"},"xlsx":{"version":"0.18.5","url":"https://sheetjs.com/","license":"Apache-2.0"}};
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
StyleSheet,
|
|
4
|
-
} from 'react-native';
|
|
5
|
-
import {TouchableRipple} from "react-native-paper";
|
|
6
|
-
import CrossFadeIcon from 'react-native-paper/lib/commonjs/components/CrossFadeIcon';
|
|
7
|
-
import Surface from '$ecomponents/Surface';
|
|
8
|
-
import { IconButton } from 'react-native-paper';
|
|
9
|
-
import PropTypes from "prop-types";
|
|
10
|
-
import theme,{StyleProp,Colors} from "$theme";
|
|
11
|
-
import {defaultStr} from "$cutils";
|
|
12
|
-
|
|
13
|
-
const IconButtonComponent = ({
|
|
14
|
-
icon,
|
|
15
|
-
iconColor: customIconColor,
|
|
16
|
-
containerColor,
|
|
17
|
-
size = 24,
|
|
18
|
-
accessibilityLabel,
|
|
19
|
-
disabled,
|
|
20
|
-
onPress,
|
|
21
|
-
selected = false,
|
|
22
|
-
animated = false,
|
|
23
|
-
mode,
|
|
24
|
-
containerProps,
|
|
25
|
-
style,
|
|
26
|
-
testID,
|
|
27
|
-
color,
|
|
28
|
-
...rest
|
|
29
|
-
}) => {
|
|
30
|
-
const IconComponent = animated ? CrossFadeIcon : IconButton;
|
|
31
|
-
testID = defaultStr(testID,"RN_IconButtonComponent");
|
|
32
|
-
containerProps = defaultObj(containerProps);
|
|
33
|
-
const containerStyle = StyleSheet.flatten(containerProps.style) || {};
|
|
34
|
-
const backgroundColor = Colors.isValid(containerColor)? containerColor : Colors.isValid(containerStyle.color) ? containerStyle.color : undefined;
|
|
35
|
-
const iconColor = Colors.isValid(customIconColor)? customIconColor : Colors.isValid(color)? color : theme.colors.text;
|
|
36
|
-
const borderColor = theme.colors.outline || theme.colors.divider;
|
|
37
|
-
const rippleColor = Colors.setAlpha(iconColor,0.32);
|
|
38
|
-
const buttonSize = size * 1.5;
|
|
39
|
-
const borderStyles = {
|
|
40
|
-
borderWidth: 0,
|
|
41
|
-
borderRadius: buttonSize / 2,
|
|
42
|
-
borderColor,
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
return (
|
|
46
|
-
<Surface
|
|
47
|
-
testID = {testID+"_Container"}
|
|
48
|
-
style={
|
|
49
|
-
[
|
|
50
|
-
{
|
|
51
|
-
backgroundColor,
|
|
52
|
-
width: buttonSize,
|
|
53
|
-
height: buttonSize,
|
|
54
|
-
},
|
|
55
|
-
styles.container,
|
|
56
|
-
borderStyles,
|
|
57
|
-
disabled && styles.disabled,
|
|
58
|
-
style,
|
|
59
|
-
]
|
|
60
|
-
}
|
|
61
|
-
>
|
|
62
|
-
<TouchableRipple
|
|
63
|
-
borderless
|
|
64
|
-
centered
|
|
65
|
-
onPress={onPress}
|
|
66
|
-
rippleColor={rippleColor}
|
|
67
|
-
accessibilityLabel={accessibilityLabel}
|
|
68
|
-
style={styles.touchable}
|
|
69
|
-
// @ts-expect-error We keep old a11y props for backwards compat with old RN versions
|
|
70
|
-
accessibilityTraits={disabled ? ['button', 'disabled'] : 'button'}
|
|
71
|
-
accessibilityComponentType="button"
|
|
72
|
-
role="button"
|
|
73
|
-
accessibilityState={{ disabled }}
|
|
74
|
-
disabled={disabled}
|
|
75
|
-
hitSlop={
|
|
76
|
-
TouchableRipple.supported
|
|
77
|
-
? { top: 10, left: 10, bottom: 10, right: 10 }
|
|
78
|
-
: { top: 6, left: 6, bottom: 6, right: 6 }
|
|
79
|
-
}
|
|
80
|
-
{...rest}
|
|
81
|
-
testID = {testID}
|
|
82
|
-
>
|
|
83
|
-
<IconComponent testID={testID+"_Icon"} color={iconColor} source={icon} size={size} />
|
|
84
|
-
</TouchableRipple>
|
|
85
|
-
</Surface>
|
|
86
|
-
);
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const styles = StyleSheet.create({
|
|
90
|
-
container: {
|
|
91
|
-
overflow: 'hidden',
|
|
92
|
-
margin: 6,
|
|
93
|
-
elevation: 0,
|
|
94
|
-
},
|
|
95
|
-
touchable: {
|
|
96
|
-
flexGrow: 1,
|
|
97
|
-
justifyContent: 'center',
|
|
98
|
-
alignItems: 'center',
|
|
99
|
-
},
|
|
100
|
-
disabled: {
|
|
101
|
-
opacity: 0.32,
|
|
102
|
-
},
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
IconButtonComponent.propTypes = {
|
|
106
|
-
/**
|
|
107
|
-
* Icon to display.
|
|
108
|
-
*/
|
|
109
|
-
icon: PropTypes.oneOfType(PropTypes.string,PropTypes.object),
|
|
110
|
-
/**
|
|
111
|
-
* @supported Available in v5.x
|
|
112
|
-
* Mode of the icon button. By default there is no specified mode - only pressable icon will be rendered.
|
|
113
|
-
*/
|
|
114
|
-
mode : PropTypes.oneOf([
|
|
115
|
-
'outlined','contained' ,'contained-tonal'
|
|
116
|
-
]),
|
|
117
|
-
/**
|
|
118
|
-
* @renamed Renamed from 'color' to 'iconColor' in v5.x
|
|
119
|
-
* Color of the icon.
|
|
120
|
-
*/
|
|
121
|
-
iconColor: PropTypes.string,
|
|
122
|
-
/**
|
|
123
|
-
* @supported Available in v5.x
|
|
124
|
-
* Background color of the icon container.
|
|
125
|
-
*/
|
|
126
|
-
containerColor: PropTypes.string,
|
|
127
|
-
/**
|
|
128
|
-
* @supported Available in v5.x
|
|
129
|
-
* Whether icon button is selected. A selected button receives alternative combination of icon and container colors.
|
|
130
|
-
*/
|
|
131
|
-
selected: PropTypes.bool,
|
|
132
|
-
/**
|
|
133
|
-
* Size of the icon.
|
|
134
|
-
*/
|
|
135
|
-
size : PropTypes.number,
|
|
136
|
-
/**
|
|
137
|
-
* Whether the button is disabled. A disabled button is greyed out and `onPress` is not called on touch.
|
|
138
|
-
*/
|
|
139
|
-
disabled: PropTypes.bool,
|
|
140
|
-
/**
|
|
141
|
-
* Whether an icon change is animated.
|
|
142
|
-
*/
|
|
143
|
-
animated: PropTypes.bool,
|
|
144
|
-
/**
|
|
145
|
-
* Accessibility label for the button. This is read by the screen reader when the user taps the button.
|
|
146
|
-
*/
|
|
147
|
-
accessibilityLabel: PropTypes.string,
|
|
148
|
-
/**
|
|
149
|
-
* Function to execute on press.
|
|
150
|
-
*/
|
|
151
|
-
onPress : PropTypes.func,//(e: GestureResponderEvent) => void;
|
|
152
|
-
style : StyleProp,
|
|
153
|
-
ref : PropTypes.object,
|
|
154
|
-
}
|
|
155
|
-
export default theme.withStyles(IconButtonComponent,{displayName:"IconButtonComponent"});
|