@fto-consult/expo-ui 1.1.3 → 1.1.5
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/babel.config.alias.js +13 -9
- package/babel.config.js +23 -6
- package/expo.metro.config.js +35 -12
- package/is-os-case-sensitive.js +27 -0
- package/metro.config.js +4 -1
- package/package.json +102 -99
- package/parent-package.js +2 -2
- package/src/App.js +2 -1
- package/src/auth/Login.js +13 -9
- package/src/components/AutoLink/index.js +4 -0
- package/src/components/Br/index.js +3 -4
- package/src/components/Chart/{appexchart.3.5.text → appexchart.3.5.html} +0 -0
- package/src/components/Chart/index.native.js +1 -4
- package/src/components/Html/View.js +1 -1
- package/src/components/Html/index.js +1 -0
- package/src/components/HtmlElements/index.js +9 -0
- package/src/components/Logo/Logo.js +15 -22
- package/src/components/Logo/defaultComponent.js +5 -0
- package/src/index.js +14 -14
- package/src/layouts/Screen/Screen.js +14 -169
- package/src/layouts/Screen/ScreenWithOrWithoutAuthContainer.js +179 -0
- package/src/layouts/Screen/ScreenWithoutAuthContainer.js +18 -0
- package/src/layouts/Screen/index.js +2 -1
- package/src/navigation/Drawer/index.js +6 -2
- package/src/screens/Auth/index.js +2 -3
- package/src/screens/index.js +3 -4
- package/src/components/Br/index.web.js +0 -3
- package/src/screens/Auth/routes.js +0 -9
package/babel.config.alias.js
CHANGED
|
@@ -18,7 +18,12 @@ module.exports = (opts)=>{
|
|
|
18
18
|
r["$enavigation"] = path.resolve(expo,"navigation");
|
|
19
19
|
r["$escreens"] = path.resolve(expo,"screens");
|
|
20
20
|
r["$escreen"] = path.resolve(expo,"layouts/Screen");
|
|
21
|
+
r["$eassets"] = path.resolve(dir,"assets");
|
|
22
|
+
|
|
23
|
+
///pour personnaliser les écrans de l'application, il suffit de redefinir l'alis $screens, pointant vers le repertoire racine des écrans personnalisés
|
|
24
|
+
///cependant, ce repertoire doit contenir un fichier mainScreens.js qui contient la liste de tous les écrans de lapplicaiton
|
|
21
25
|
r["$screens"] = r["$screens"] || r["$escreens"];
|
|
26
|
+
|
|
22
27
|
r["$expo"] = r["$expo-ui"] = expo;
|
|
23
28
|
r["$epreloader"] = path.resolve(expo,"components/Preloader");
|
|
24
29
|
r["$eform"] = path.resolve(expo,"components","Form");
|
|
@@ -56,16 +61,15 @@ module.exports = (opts)=>{
|
|
|
56
61
|
if(r["$loginComponent"] == r["$cloginComponent"]){
|
|
57
62
|
r["$loginComponent"] = path.resolve(expo,"auth","Login");
|
|
58
63
|
}
|
|
64
|
+
|
|
65
|
+
/*** alias pour le composant logo par défaut : */
|
|
66
|
+
r["$elogoComponent"] = path.resolve(expo,"components","Logo","defaultComponent");
|
|
67
|
+
if(!r["$logoComponent"]){
|
|
68
|
+
r["$logoComponent"] = r["$elogoComponent"];
|
|
69
|
+
}
|
|
70
|
+
|
|
59
71
|
if(typeof opts.mutator =='function'){
|
|
60
72
|
opts.mutator(r);
|
|
61
73
|
}
|
|
62
|
-
|
|
63
|
-
for(let i in r){
|
|
64
|
-
aliases.push({
|
|
65
|
-
root: r[i],
|
|
66
|
-
rootPathPrefix: i,
|
|
67
|
-
rootPathSuffix: '',
|
|
68
|
-
})
|
|
69
|
-
}
|
|
70
|
-
return aliases;
|
|
74
|
+
return r;
|
|
71
75
|
}
|
package/babel.config.js
CHANGED
|
@@ -3,21 +3,38 @@ module.exports = function(api,opts) {
|
|
|
3
3
|
///les chemin vers la variable d'environnement, le chemin du fichier .env,@see : https://github.com/brysgo/babel-plugin-inline-dotenv
|
|
4
4
|
const environmentPath = opts.environmentPath || opts.envPath;
|
|
5
5
|
const path = require("path");
|
|
6
|
+
const fs = require("fs");
|
|
6
7
|
const dir = path.resolve(__dirname);
|
|
7
8
|
api.cache(true);
|
|
8
|
-
const
|
|
9
|
+
const inlineDovOptions = {};
|
|
10
|
+
const options = {base:dir,...opts,platform:"expo"};
|
|
11
|
+
/*** 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 */
|
|
12
|
+
if(!environmentPath || typeof environmentPath !== 'string'){
|
|
13
|
+
const baseStr = typeof options.base =='string' && fs.existsSync(options.base)? options.base : typeof options.dir =='string' && fs.existsSync(options.dir)? options.dir : dir;
|
|
14
|
+
environmentPath = path.resolve(baseStr,".env");
|
|
15
|
+
} else {
|
|
16
|
+
environmentPath = "";
|
|
17
|
+
}
|
|
18
|
+
if(environmentPath && fs.existsSync(environmentPath)){
|
|
19
|
+
// File ".env" will be created or overwritten by default.
|
|
20
|
+
try {
|
|
21
|
+
fs.copyFileSync(environmentPath, path.resolve(dir,'.env'));
|
|
22
|
+
}
|
|
23
|
+
catch (e){
|
|
24
|
+
inlineDovOptions.path = environmentPath;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const alias = require("./babel.config.alias")(options);
|
|
9
28
|
return {
|
|
10
29
|
presets: [
|
|
11
30
|
['babel-preset-expo'],
|
|
12
31
|
["@babel/preset-react", {"runtime": "automatic"}],
|
|
13
32
|
],
|
|
14
33
|
plugins : [
|
|
15
|
-
[
|
|
34
|
+
["inline-dotenv",inlineDovOptions],
|
|
35
|
+
["module-resolver", {"alias": alias}],
|
|
16
36
|
['react-native-reanimated/plugin'],
|
|
17
37
|
['transform-inline-environment-variables'],
|
|
18
|
-
|
|
19
|
-
...(environmentPath?{path:environmentPath} : {})
|
|
20
|
-
}]
|
|
21
|
-
]
|
|
38
|
+
],
|
|
22
39
|
};
|
|
23
40
|
};
|
package/expo.metro.config.js
CHANGED
|
@@ -1,26 +1,49 @@
|
|
|
1
1
|
const { getDefaultConfig } = require('@expo/metro-config');
|
|
2
2
|
const path = require("path");
|
|
3
|
+
const isCaseSensitive = require("./is-os-case-sensitive");
|
|
3
4
|
module.exports = (opts)=>{
|
|
4
5
|
opts = opts && typeof opts =='object'? opts : {};
|
|
5
|
-
let {dir,nodeModulesPaths} = opts;
|
|
6
|
+
let {dir,nodeModulesPaths,assetExts,sourceExts} = opts;
|
|
6
7
|
nodeModulesPaths = Array.isArray(nodeModulesPaths)? nodeModulesPaths : [];
|
|
8
|
+
assetExts = Array.isArray(assetExts)? assetExts: [];
|
|
9
|
+
sourceExts= Array.isArray(sourceExts)?sourceExts : [];
|
|
7
10
|
dir = dir || path.resolve(__dirname);
|
|
8
11
|
const projectRoot = path.resolve(dir);
|
|
9
|
-
const
|
|
12
|
+
const localDir = path.resolve(__dirname);
|
|
10
13
|
const config = getDefaultConfig(projectRoot);
|
|
11
|
-
config.watchFolders = [
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
config.watchFolders = [projectRoot];
|
|
15
|
+
if(projectRoot !== localDir){
|
|
16
|
+
config.watchFolders.push(localDir);
|
|
17
|
+
}
|
|
18
|
+
config.resolver.assetExts = [
|
|
19
|
+
...config.resolver.assetExts,
|
|
20
|
+
...assetExts,
|
|
21
|
+
"db",
|
|
22
|
+
"txt"
|
|
23
|
+
];
|
|
20
24
|
config.resolver.sourceExts = [
|
|
21
25
|
...config.resolver.sourceExts,
|
|
22
|
-
|
|
26
|
+
...sourceExts,"txt",
|
|
27
|
+
'jsx', 'js','tsx',
|
|
23
28
|
]
|
|
29
|
+
const allNodePaths = [
|
|
30
|
+
path.resolve(projectRoot, 'node_modules'),
|
|
31
|
+
path.resolve(localDir, 'node_modules'),
|
|
32
|
+
...nodeModulesPaths,
|
|
33
|
+
];
|
|
34
|
+
const existingNodesPath= {},nPaths = [];
|
|
35
|
+
allNodePaths.map(p=>{
|
|
36
|
+
if(!p || typeof p !='string') return;
|
|
37
|
+
if(isCaseSensitive){
|
|
38
|
+
p = p.toLocaleLowerCase();
|
|
39
|
+
}
|
|
40
|
+
if(!existingNodesPath[p]){
|
|
41
|
+
existingNodesPath[p] = true;
|
|
42
|
+
nPaths.push(p);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
config.resolver.nodeModulesPaths = nPaths;
|
|
24
47
|
// 3. Force Metro to resolve (sub)dependencies only from the `nodeModulesPaths`
|
|
25
48
|
config.resolver.disableHierarchicalLookup = true;
|
|
26
49
|
return config;
|
|
@@ -0,0 +1,27 @@
|
|
|
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.
|
|
4
|
+
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const dir = path.resolve(__dirname);
|
|
7
|
+
const fs = require("fs");
|
|
8
|
+
|
|
9
|
+
/*** check weather os is case sensitive
|
|
10
|
+
* @see : https://stackoverflow.com/questions/27367261/check-if-file-exists-case-sensitive/52908385#52908385
|
|
11
|
+
*/
|
|
12
|
+
function fileExistsWithCaseSync(filepath) {
|
|
13
|
+
var dir = path.dirname(filepath);
|
|
14
|
+
if (dir === '/' || dir === '.') return true;
|
|
15
|
+
var filenames = fs.readdirSync(dir);
|
|
16
|
+
if (filenames.indexOf(path.basename(filepath)) === -1) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return fileExistsWithCaseSync(dir);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/***vérifie si le système supporte la cassse où non
|
|
23
|
+
* c'est à dire si 2 noms de fichiers ayant la case différentes sont considérés comme le même où pas
|
|
24
|
+
*/
|
|
25
|
+
module.exports = (()=>{
|
|
26
|
+
return fileExistsWithCaseSync(path.resolve(dir,"metro.config.js")) == fileExistsWithCaseSync(path.resolve(dir,"Metro.config.js"))
|
|
27
|
+
})();
|
package/metro.config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,99 +1,102 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@fto-consult/expo-ui",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"description": "Bibliothèque de composants UI Expo,react-native",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"publish": "npm publish --access=public",
|
|
8
|
-
"unpublish": "npm -f unpublish @fto-consult/expo-ui",
|
|
9
|
-
"build-web": "",
|
|
10
|
-
"dev": "npx expo start -c --no-minify",
|
|
11
|
-
"start": "npx expo start --dev --no-minify",
|
|
12
|
-
"start-d": "npx expo start -c --no-dev --no-minify",
|
|
13
|
-
"start-p": "npm run start-d",
|
|
14
|
-
"expo-start-client": "npx expo start --dev --no-minify --dev-client",
|
|
15
|
-
"start-m": "npx expo start - c--dev--no -minify",
|
|
16
|
-
"android": "npx expo start --android -c",
|
|
17
|
-
"ios": "npx expo start --ios",
|
|
18
|
-
"web": "npx expo start --web",
|
|
19
|
-
"web-c": "npx expo start --web -c",
|
|
20
|
-
"eject": "expo eject",
|
|
21
|
-
"emulator": "npm run android-emulator",
|
|
22
|
-
"web-server": "npx serve web-build",
|
|
23
|
-
"build-android": "eas build --clear-cache -p android --profile preview",
|
|
24
|
-
"build-android-local": "eas build --platform android --local",
|
|
25
|
-
"build-android-dist": "eas build --clear-cache -p android",
|
|
26
|
-
"build-ios": "eas build --clear-cache -p ios --profile preview",
|
|
27
|
-
"build-ios-dist": "eas build --clear-cache -p ios",
|
|
28
|
-
"install-apk": "adb -s emulator-5554 install myapp.apk",
|
|
29
|
-
"android-emulator": "emulator -avd EMULATOR",
|
|
30
|
-
"flipper": "npx cross-env METRO_SERVER_PORT=19000 E:\\Studies\\react-native\\debugger\\Flipper-win\\Flipper.exe",
|
|
31
|
-
"build-electron": "electron-webpack && electron-builder --dir -c.compression=store",
|
|
32
|
-
"test:build": "electron-webpack && electron-builder --dir -c.compression=store -c.mac.identity=null",
|
|
33
|
-
"compile-electron": "webpack --config ./electron/webpack.config.js",
|
|
34
|
-
"compile-electron-p": "webpack --config ./electron/webpack.config.js --mode=production",
|
|
35
|
-
"electron": "electron ./electron",
|
|
36
|
-
"logcat": "adb -d logcat com.ftc.apps.salite1:E > errors.txt",
|
|
37
|
-
"logcat-export": "adb -d logcat com.ftc.apps.salite1 *:S > logcat.txt",
|
|
38
|
-
"electron-c": "npm run compile-electron && npm run electron",
|
|
39
|
-
"electron-p": "npm run compile-electron-p && npm run electron",
|
|
40
|
-
"update-app-version": "node ./update-app-version.js",
|
|
41
|
-
"find-licenses": "node ./find-licenses.js",
|
|
42
|
-
"fix-dependencies": "expo doctor --fix-dependencies"
|
|
43
|
-
},
|
|
44
|
-
"repository": {
|
|
45
|
-
"type": "git",
|
|
46
|
-
"url": "git+https://github.com/borispipo/expo-ui.git"
|
|
47
|
-
},
|
|
48
|
-
"keywords": [
|
|
49
|
-
"Expo",
|
|
50
|
-
"React-Native"
|
|
51
|
-
],
|
|
52
|
-
"author": "Boris Fouomene",
|
|
53
|
-
"license": "ISC",
|
|
54
|
-
"bugs": {
|
|
55
|
-
"url": "https://github.com/borispipo/expo-ui/issues"
|
|
56
|
-
},
|
|
57
|
-
"homepage": "https://github.com/borispipo/expo-ui#readme",
|
|
58
|
-
"dependencies": {
|
|
59
|
-
"@babel/preset-react": "^7.18.6",
|
|
60
|
-
"@emotion/native": "^11.10.0",
|
|
61
|
-
"@expo/
|
|
62
|
-
"@expo/
|
|
63
|
-
"@
|
|
64
|
-
"@
|
|
65
|
-
"@
|
|
66
|
-
"@react-native-
|
|
67
|
-
"@react-
|
|
68
|
-
"@react-
|
|
69
|
-
"@
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"babel-plugin-
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"expo
|
|
76
|
-
"expo-
|
|
77
|
-
"expo-
|
|
78
|
-
"expo-
|
|
79
|
-
"expo-
|
|
80
|
-
"expo-
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
"
|
|
84
|
-
"
|
|
85
|
-
"
|
|
86
|
-
"react-
|
|
87
|
-
"react-
|
|
88
|
-
"react-
|
|
89
|
-
"react-native
|
|
90
|
-
"react-native-
|
|
91
|
-
"react-native-
|
|
92
|
-
"react-native-
|
|
93
|
-
"react-native-
|
|
94
|
-
"react-native-
|
|
95
|
-
"react-native-
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
|
|
99
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@fto-consult/expo-ui",
|
|
3
|
+
"version": "1.1.5",
|
|
4
|
+
"description": "Bibliothèque de composants UI Expo,react-native",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"publish": "npm publish --access=public",
|
|
8
|
+
"unpublish": "npm -f unpublish @fto-consult/expo-ui",
|
|
9
|
+
"build-web": "",
|
|
10
|
+
"dev": "npx expo start -c --no-minify",
|
|
11
|
+
"start": "npx expo start --dev --no-minify",
|
|
12
|
+
"start-d": "npx expo start -c --no-dev --no-minify",
|
|
13
|
+
"start-p": "npm run start-d",
|
|
14
|
+
"expo-start-client": "npx expo start --dev --no-minify --dev-client",
|
|
15
|
+
"start-m": "npx expo start - c--dev--no -minify",
|
|
16
|
+
"android": "npx expo start --android -c",
|
|
17
|
+
"ios": "npx expo start --ios",
|
|
18
|
+
"web": "npx expo start --web",
|
|
19
|
+
"web-c": "npx expo start --web -c",
|
|
20
|
+
"eject": "expo eject",
|
|
21
|
+
"emulator": "npm run android-emulator",
|
|
22
|
+
"web-server": "npx serve web-build",
|
|
23
|
+
"build-android": "eas build --clear-cache -p android --profile preview",
|
|
24
|
+
"build-android-local": "eas build --platform android --local",
|
|
25
|
+
"build-android-dist": "eas build --clear-cache -p android",
|
|
26
|
+
"build-ios": "eas build --clear-cache -p ios --profile preview",
|
|
27
|
+
"build-ios-dist": "eas build --clear-cache -p ios",
|
|
28
|
+
"install-apk": "adb -s emulator-5554 install myapp.apk",
|
|
29
|
+
"android-emulator": "emulator -avd EMULATOR",
|
|
30
|
+
"flipper": "npx cross-env METRO_SERVER_PORT=19000 E:\\Studies\\react-native\\debugger\\Flipper-win\\Flipper.exe",
|
|
31
|
+
"build-electron": "electron-webpack && electron-builder --dir -c.compression=store",
|
|
32
|
+
"test:build": "electron-webpack && electron-builder --dir -c.compression=store -c.mac.identity=null",
|
|
33
|
+
"compile-electron": "webpack --config ./electron/webpack.config.js",
|
|
34
|
+
"compile-electron-p": "webpack --config ./electron/webpack.config.js --mode=production",
|
|
35
|
+
"electron": "electron ./electron",
|
|
36
|
+
"logcat": "adb -d logcat com.ftc.apps.salite1:E > errors.txt",
|
|
37
|
+
"logcat-export": "adb -d logcat com.ftc.apps.salite1 *:S > logcat.txt",
|
|
38
|
+
"electron-c": "npm run compile-electron && npm run electron",
|
|
39
|
+
"electron-p": "npm run compile-electron-p && npm run electron",
|
|
40
|
+
"update-app-version": "node ./update-app-version.js",
|
|
41
|
+
"find-licenses": "node ./find-licenses.js",
|
|
42
|
+
"fix-dependencies": "expo doctor --fix-dependencies"
|
|
43
|
+
},
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "git+https://github.com/borispipo/expo-ui.git"
|
|
47
|
+
},
|
|
48
|
+
"keywords": [
|
|
49
|
+
"Expo",
|
|
50
|
+
"React-Native"
|
|
51
|
+
],
|
|
52
|
+
"author": "Boris Fouomene",
|
|
53
|
+
"license": "ISC",
|
|
54
|
+
"bugs": {
|
|
55
|
+
"url": "https://github.com/borispipo/expo-ui/issues"
|
|
56
|
+
},
|
|
57
|
+
"homepage": "https://github.com/borispipo/expo-ui#readme",
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"@babel/preset-react": "^7.18.6",
|
|
60
|
+
"@emotion/native": "^11.10.0",
|
|
61
|
+
"@expo/html-elements": "^0.2.0",
|
|
62
|
+
"@expo/metro-config": "^0.4.0",
|
|
63
|
+
"@expo/webpack-config": "^0.17.2",
|
|
64
|
+
"@fto-consult/common": "^1.1.28",
|
|
65
|
+
"@gorhom/portal": "^1.0.14",
|
|
66
|
+
"@react-native-async-storage/async-storage": "~1.17.3",
|
|
67
|
+
"@react-native-community/datetimepicker": "6.2.0",
|
|
68
|
+
"@react-native-community/netinfo": "9.3.0",
|
|
69
|
+
"@react-navigation/native": "^6.0.13",
|
|
70
|
+
"@react-navigation/native-stack": "^6.9.1",
|
|
71
|
+
"@shopify/flash-list": "1.1.0",
|
|
72
|
+
"babel-plugin-inline-dotenv": "^1.7.0",
|
|
73
|
+
"babel-plugin-module-resolver": "^4.1.0",
|
|
74
|
+
"babel-plugin-transform-inline-environment-variables": "^0.4.4",
|
|
75
|
+
"expo": "^46.0.15",
|
|
76
|
+
"expo-camera": "~12.3.0",
|
|
77
|
+
"expo-linking": "~3.2.2",
|
|
78
|
+
"expo-sqlite": "~10.3.0",
|
|
79
|
+
"expo-status-bar": "~1.4.0",
|
|
80
|
+
"expo-system-ui": "~1.3.0",
|
|
81
|
+
"expo-web-browser": "~11.0.0",
|
|
82
|
+
"google-libphonenumber": "^3.2.31",
|
|
83
|
+
"htmlparser2-without-node-native": "^3.9.2",
|
|
84
|
+
"parent-package-json": "^2.0.1",
|
|
85
|
+
"prop-types": "^15.8.1",
|
|
86
|
+
"react-apexcharts": "^1.4.0",
|
|
87
|
+
"react-content-loader": "^6.2.0",
|
|
88
|
+
"react-dom": "18.0.0",
|
|
89
|
+
"react-native": "0.69.6",
|
|
90
|
+
"react-native-big-list": "^1.5.5",
|
|
91
|
+
"react-native-gesture-handler": "~2.5.0",
|
|
92
|
+
"react-native-paper": "^4.12.5",
|
|
93
|
+
"react-native-paper-dates": "^0.9.2",
|
|
94
|
+
"react-native-reanimated": "~2.9.1",
|
|
95
|
+
"react-native-safe-area-context": "4.3.1",
|
|
96
|
+
"react-native-svg": "12.3.0",
|
|
97
|
+
"react-native-web": "~0.18.7",
|
|
98
|
+
"react-native-webview": "11.23.0",
|
|
99
|
+
"sharp-cli": "^2.1.0",
|
|
100
|
+
"tippy.js": "^6.3.7"
|
|
101
|
+
}
|
|
102
|
+
}
|
package/parent-package.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// license that can be found in the LICENSE file.
|
|
4
4
|
|
|
5
5
|
/**** cette fonction a pour rôle de retourner le package parent à celui ci */
|
|
6
|
-
module.
|
|
7
|
-
const pathToParent = require("parent-package-json"); // Will return false if no parent exists
|
|
6
|
+
module.exports = ()=>{
|
|
7
|
+
const pathToParent = require("parent-package-json")(); // Will return false if no parent exists
|
|
8
8
|
if (pathToParent !== false) {
|
|
9
9
|
return pathToParent.path;
|
|
10
10
|
}
|
package/src/App.js
CHANGED
|
@@ -20,6 +20,7 @@ import {GestureHandlerRootView} from "react-native-gesture-handler";
|
|
|
20
20
|
import StatusBar from "$ecomponents/StatusBar";
|
|
21
21
|
import SimpleSelect from '$ecomponents/SimpleSelect';
|
|
22
22
|
import {Provider as AlertProvider} from '$ecomponents/Dialog/confirm/Alert';
|
|
23
|
+
import APP from "$app";
|
|
23
24
|
|
|
24
25
|
export default function getIndex(options){
|
|
25
26
|
const {App} = defaultObj(options);
|
|
@@ -35,7 +36,7 @@ export default function getIndex(options){
|
|
|
35
36
|
theme,
|
|
36
37
|
}),[theme]);
|
|
37
38
|
const child = <Index theme={theme}/>;
|
|
38
|
-
const children = typeof App =='function'? App({children:child}) : child;
|
|
39
|
+
const children = typeof App =='function'? App({children:child,APP}) : child;
|
|
39
40
|
return (
|
|
40
41
|
<GestureHandlerRootView style={{ flex: 1 }}>
|
|
41
42
|
<PaperProvider theme={theme}>
|
package/src/auth/Login.js
CHANGED
|
@@ -15,10 +15,12 @@ import View from "$ecomponents/View";
|
|
|
15
15
|
import Avatar from "$ecomponents/Avatar";
|
|
16
16
|
import Surface from "$ecomponents/Surface";
|
|
17
17
|
import {Provider as DialogProvider} from "$ecomponents/Dialog";
|
|
18
|
-
import
|
|
18
|
+
import ScreenWithoutAuthContainer from "$escreen/ScreenWithoutAuthContainer";
|
|
19
19
|
import {getTitle} from "$escreens/Auth/utils";
|
|
20
20
|
import {isWeb} from "$cplatform";
|
|
21
|
+
|
|
21
22
|
import getLoginProps from "$getLoginProps";
|
|
23
|
+
const getProps = typeof getLoginProps =='function'? getLoginProps : x=>null;
|
|
22
24
|
|
|
23
25
|
const WIDTH = 400;
|
|
24
26
|
|
|
@@ -31,7 +33,7 @@ export default function LoginComponent(props){
|
|
|
31
33
|
const previousButtonRef = React.useRef(null);
|
|
32
34
|
const dialogProviderRef = React.useRef(null);
|
|
33
35
|
const backgroundColor = theme.colors.surface;
|
|
34
|
-
const Wrapper = withPortal ?
|
|
36
|
+
const Wrapper = withPortal ? ScreenWithoutAuthContainer : View;
|
|
35
37
|
const _getForm = x=> getForm(formName);
|
|
36
38
|
|
|
37
39
|
const auth = useAuth();
|
|
@@ -43,13 +45,12 @@ export default function LoginComponent(props){
|
|
|
43
45
|
const getData = ()=>{
|
|
44
46
|
const form = _getForm();
|
|
45
47
|
if(form && form.getData){
|
|
46
|
-
return extendObj(state.data,form.getData());
|
|
48
|
+
return extendObj({},state.data,form.getData());
|
|
47
49
|
}
|
|
48
50
|
return defaultObj(props.data);
|
|
49
51
|
}
|
|
50
52
|
const goToFirstStep = ()=>{
|
|
51
|
-
|
|
52
|
-
setState({...state,step:1,data});
|
|
53
|
+
setState({...state,step:1,data:getData()});
|
|
53
54
|
}
|
|
54
55
|
const focusField = (fieldName)=>{
|
|
55
56
|
const form = _getForm();
|
|
@@ -73,9 +74,9 @@ export default function LoginComponent(props){
|
|
|
73
74
|
},1000)
|
|
74
75
|
}
|
|
75
76
|
},[withPortal])
|
|
76
|
-
const getProps = typeof getLoginProps =='function'? getLoginProps : x=>null;
|
|
77
77
|
const {header,children,data:loginData,canGoToNext,keyboardEvents,onSuccess:onLoginSuccess,canSubmit:canSubmitForm,onStepChange,...loginProps} = defaultObj(getProps({
|
|
78
78
|
...state,
|
|
79
|
+
state,
|
|
79
80
|
getForm,
|
|
80
81
|
getData,
|
|
81
82
|
focusField,
|
|
@@ -105,7 +106,10 @@ export default function LoginComponent(props){
|
|
|
105
106
|
notifyUser("Impossible de valider le formulaire car celui-ci semble invalide")
|
|
106
107
|
return;
|
|
107
108
|
}
|
|
108
|
-
const args = {data,form,step,nextButtonRef,previousButtonRef};
|
|
109
|
+
const args = {data,form,state,step,nextButtonRef,previousButtonRef};
|
|
110
|
+
if(nextButtonRef.current && nextButtonRef.current.isDisabled()){
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
109
113
|
if(typeof canGoToNext =='function'){
|
|
110
114
|
const s = canGoToNext(args);
|
|
111
115
|
if(s === false) return;
|
|
@@ -119,7 +123,7 @@ export default function LoginComponent(props){
|
|
|
119
123
|
return auth.signIn(data).then((a)=>{
|
|
120
124
|
if(typeof onLoginSuccess =='function' && onLoginSuccess(a)=== false) return;
|
|
121
125
|
if(isFunction(onSuccess)){
|
|
122
|
-
onSuccess(
|
|
126
|
+
onSuccess(data);
|
|
123
127
|
} else {
|
|
124
128
|
navigate("Home");
|
|
125
129
|
}
|
|
@@ -127,7 +131,7 @@ export default function LoginComponent(props){
|
|
|
127
131
|
Preloader.close();
|
|
128
132
|
})
|
|
129
133
|
} else {
|
|
130
|
-
setState({...state,step:step+1
|
|
134
|
+
setState({...state,step:step+1,data})
|
|
131
135
|
}
|
|
132
136
|
}
|
|
133
137
|
|
|
@@ -1,3 +1,7 @@
|
|
|
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.
|
|
4
|
+
|
|
1
5
|
import * as Linking from 'expo-linking';
|
|
2
6
|
import { Pressable } from 'react-native';
|
|
3
7
|
import {isValidUrl,isValidEmail,defaultStr,isSms} from "$utils";
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
1
|
+
import {BR } from '@expo/html-elements';
|
|
2
|
+
|
|
3
|
+
export default BR;
|
|
File without changes
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import FileSystem from "$file-system";
|
|
2
|
-
import appexChartCode from "./appexchart.3.5.
|
|
2
|
+
import appexChartCode from "./appexchart.3.5.html";
|
|
3
3
|
import React from "$react";
|
|
4
4
|
import WebView from "$ecomponents/WebView";
|
|
5
|
-
import HTMLView from '$ecomponents/Html/View';
|
|
6
5
|
import {defaultStr,uniqid} from "$utils";
|
|
7
6
|
import View from "$ecomponents/View";
|
|
8
7
|
|
|
9
8
|
let appexchartJSString = null;
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
10
|
export const ChartComponent = React.forwardRef(({options,containerId,...props},ref)=>{
|
|
14
11
|
const containerIdRef = React.useRef(defaultStr(containerId,uniqid("chart-container-id")))
|
|
15
12
|
const appexChartJS = appexchartJSString? (appexchartJSString+"\n"):"";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/***@see : https://github.com/jsdf/react-native-htmlview */
|
|
2
2
|
import React, {PureComponent} from 'react';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
|
-
import htmlToElement from './
|
|
4
|
+
import htmlToElement from './HtmlToElement';
|
|
5
5
|
import {Linking, Platform, StyleSheet, View} from 'react-native';
|
|
6
6
|
import {StyleProp} from "$theme";
|
|
7
7
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./HtmlToElement";
|
|
@@ -0,0 +1,9 @@
|
|
|
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.
|
|
4
|
+
/***@see : https://www.npmjs.com/package/@expo/html-elements */
|
|
5
|
+
export * from "@expo/html-elements";
|
|
6
|
+
|
|
7
|
+
import {BR} from "@expo/html-elements";
|
|
8
|
+
|
|
9
|
+
export {BR as Br};
|
|
@@ -3,17 +3,18 @@ import { Component } from "react";
|
|
|
3
3
|
import {isNativeMobile} from "$cplatform";
|
|
4
4
|
import {Image} from "react-native";
|
|
5
5
|
import View from "$ecomponents/View";
|
|
6
|
-
import
|
|
6
|
+
import React from "$react";
|
|
7
7
|
import theme,{remToPixel,Colors,flattenStyle} from '$theme';
|
|
8
8
|
import {StyleSheet} from "react-native";
|
|
9
9
|
import source from "$assets/logo.png";
|
|
10
10
|
import {defaultStr} from "$utils";
|
|
11
|
+
import LogoComponent from "$logoComponent";
|
|
11
12
|
|
|
12
13
|
export const height = 150;
|
|
13
14
|
export const width = undefined;//300;
|
|
14
15
|
export default class Logo extends Component {
|
|
15
16
|
render(props){
|
|
16
|
-
let {icon,color,style,testID,text} = this.props;
|
|
17
|
+
let {icon,color,style,testID,logo,text} = this.props;
|
|
17
18
|
testID = defaultStr(testID,"RN_LogoComponent");
|
|
18
19
|
const styles = getStyle(style,color);
|
|
19
20
|
return <View testID={testID} style={styles.container}>
|
|
@@ -28,12 +29,7 @@ export default class Logo extends Component {
|
|
|
28
29
|
)}
|
|
29
30
|
/>}
|
|
30
31
|
</View> : null}
|
|
31
|
-
{text !== false ? <
|
|
32
|
-
<Label style={styles.firstText}>XPose</Label>
|
|
33
|
-
<Label style={styles.secondText}>F</Label>
|
|
34
|
-
<Label style={styles.thirdText}>T</Label>
|
|
35
|
-
<Label style={styles.fourthText}>C</Label>
|
|
36
|
-
</View> : null}
|
|
32
|
+
{text !== false && logo !== false ? (React.isValidElement(LogoComponent)? LogoComponent : React.isComponent(LogoComponent)? <LogoComponent {...props} style={styles.logoContent} testID={testID+"_Content"} styles={styles}/> : null) : null}
|
|
37
33
|
</View>
|
|
38
34
|
}
|
|
39
35
|
|
|
@@ -44,10 +40,9 @@ const getStyle = (style,color)=>{
|
|
|
44
40
|
return {
|
|
45
41
|
...styles,
|
|
46
42
|
container : flattenStyle([styles.container,cColor,style]),
|
|
47
|
-
firstText : flattenStyle([styles.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
fourthText : flattenStyle([styles.text,cColor])
|
|
43
|
+
firstText : flattenStyle([styles.medium,cColor]),
|
|
44
|
+
large : flattenStyle([styles.medium,styles.large,cColor]),
|
|
45
|
+
small : flattenStyle([styles.medium,cColor,styles.small]),
|
|
51
46
|
};
|
|
52
47
|
}
|
|
53
48
|
|
|
@@ -73,25 +68,23 @@ const styles = StyleSheet.create({
|
|
|
73
68
|
},
|
|
74
69
|
logoContent : {
|
|
75
70
|
position:"relative",
|
|
76
|
-
//width : 160,
|
|
77
|
-
//flex : 2,
|
|
78
71
|
flexDirection : "row",
|
|
79
72
|
alignItems : "center",
|
|
80
73
|
justifyContent : "flex-start"
|
|
81
74
|
},
|
|
82
|
-
|
|
83
|
-
fontSize : remToPixel(5),
|
|
84
|
-
alignItems : "flex-start",
|
|
85
|
-
justifyContent : "center",
|
|
86
|
-
marginTop: 0//isNativeMobile() ? -5 : 0
|
|
87
|
-
},
|
|
88
|
-
thirdText : {
|
|
75
|
+
small : {
|
|
89
76
|
fontSize:remToPixel(2.5),
|
|
90
77
|
marginLeft:isNativeMobile()? -25 : -20
|
|
91
78
|
},
|
|
92
|
-
|
|
79
|
+
medium : {
|
|
93
80
|
fontSize:remToPixel(3),
|
|
94
81
|
},
|
|
82
|
+
large : {
|
|
83
|
+
fontSize : remToPixel(5),
|
|
84
|
+
alignItems : "flex-start",
|
|
85
|
+
justifyContent : "center",
|
|
86
|
+
marginTop: 0
|
|
87
|
+
},
|
|
95
88
|
})
|
|
96
89
|
|
|
97
90
|
Logo.height = height;
|
package/src/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "$react"
|
|
2
|
-
import { AppState,
|
|
2
|
+
import { AppState,BackHandler,} from "react-native";
|
|
3
|
+
import * as Linking from 'expo-linking';
|
|
3
4
|
import APP from "$capp";
|
|
4
5
|
import {AppStateService,trackIDLE,stop as stopIDLE} from "$capp/idle";
|
|
5
6
|
import { NavigationContainer} from '@react-navigation/native';
|
|
@@ -31,10 +32,10 @@ const NAVIGATION_PERSISTENCE_KEY = 'NAVIGATION_STATE';
|
|
|
31
32
|
function App(props) {
|
|
32
33
|
AppStateService.init();
|
|
33
34
|
const [initialState, setInitialState] = React.useState(undefined);
|
|
34
|
-
const appReadyRef = React.useRef(
|
|
35
|
+
const appReadyRef = React.useRef(true);
|
|
35
36
|
const [state,setState] = React.useState({
|
|
36
37
|
isLoading : true,
|
|
37
|
-
isInitialized:
|
|
38
|
+
isInitialized:true,
|
|
38
39
|
});
|
|
39
40
|
React.useEffect(() => {
|
|
40
41
|
const restoreState = () => {
|
|
@@ -99,17 +100,16 @@ function App(props) {
|
|
|
99
100
|
APP.setOnlineState(state);
|
|
100
101
|
});
|
|
101
102
|
NetInfo.fetch().catch((e)=>{});
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
});
|
|
103
|
+
init().then(()=>{
|
|
104
|
+
if(Auth.isLoggedIn()){
|
|
105
|
+
Auth.loginUser(false);
|
|
106
|
+
}
|
|
107
|
+
setState({
|
|
108
|
+
...state,isInitialized:true,isLoading : false,
|
|
109
|
+
});
|
|
110
|
+
}).catch((e)=>{
|
|
111
|
+
console.error(e," initializing app")
|
|
112
|
+
setState({...state,isInitialized:true,isLoading : false});
|
|
113
113
|
});
|
|
114
114
|
|
|
115
115
|
const Events = {}
|
|
@@ -1,172 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import PropTypes from "prop-types";
|
|
5
|
-
import {defaultObj,defaultStr,defaultNumber,defaultBool} from "$utils";
|
|
6
|
-
import ScrollView from '$ecomponents/ScrollView';
|
|
7
|
-
import View from "$ecomponents/View";
|
|
8
|
-
import { useNavigation,getScreenProps } from '$cnavigation';
|
|
9
|
-
import Fab from "$elayouts/Fab";
|
|
10
|
-
import APP from "$capp";
|
|
11
|
-
import AppBar,{createAppBarRef} from "$elayouts/AppBar";
|
|
12
|
-
import ErrorBoundary from "$ecomponents/ErrorBoundary";
|
|
13
|
-
import Portal from "$ecomponents/Portal";
|
|
14
|
-
import theme from "$theme";
|
|
15
|
-
import StatusBar from "$ecomponents/StatusBar";
|
|
16
|
-
import Auth from "$cauth";
|
|
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.
|
|
17
4
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if(!titleStr){
|
|
21
|
-
titleStr = APP.getName();
|
|
22
|
-
}
|
|
23
|
-
const dbLabel = "";
|
|
24
|
-
if(!titleStr.toLowerCase().contains(dbLabel.toLowerCase())){
|
|
25
|
-
titleStr += " ["+dbLabel+"]";
|
|
26
|
-
}
|
|
27
|
-
if(returnStr) return titleStr;
|
|
28
|
-
return typeof nTitle =='string' ? titleStr : nTitle;
|
|
29
|
-
}
|
|
5
|
+
import Container from "$cauth/Container";
|
|
6
|
+
import ScreenWithOrWithoutAuthContainer from "./ScreenWithOrWithoutAuthContainer";
|
|
30
7
|
|
|
31
|
-
export default function
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
appBarProps,
|
|
41
|
-
authProps,
|
|
42
|
-
elevation,
|
|
43
|
-
withFab,
|
|
44
|
-
appBar,
|
|
45
|
-
authRequired,
|
|
46
|
-
withDrawer,
|
|
47
|
-
allowDrawer,
|
|
48
|
-
title,
|
|
49
|
-
subtitle,
|
|
50
|
-
modal,
|
|
51
|
-
fabProps,
|
|
52
|
-
screenName,
|
|
53
|
-
containerProps,
|
|
54
|
-
testID,
|
|
55
|
-
...rest
|
|
56
|
-
} = getScreenProps(props);
|
|
57
|
-
const insets = useSafeAreaInsets();
|
|
58
|
-
testID = defaultStr(testID,"RN_MainScreenLayoutComponent")
|
|
59
|
-
containerProps = defaultObj(containerProps);
|
|
60
|
-
const backgroundColor = theme.colors.background;
|
|
61
|
-
const containerStyle = [
|
|
62
|
-
styles.container,
|
|
63
|
-
{
|
|
64
|
-
backgroundColor,
|
|
65
|
-
paddingBottom: insets.bottom,
|
|
66
|
-
paddingLeft: insets.left,
|
|
67
|
-
paddingRight: insets.right,
|
|
68
|
-
},
|
|
69
|
-
];
|
|
70
|
-
options = defaultObj(options);
|
|
71
|
-
appBarProps = defaultObj(appBarProps)
|
|
72
|
-
title = defaultVal(appBarProps.title,options.title,title);
|
|
73
|
-
subtitle = defaultVal(appBarProps.subtitle,options.subtitle,subtitle);
|
|
74
|
-
const appBarRef = createAppBarRef();
|
|
75
|
-
const navigation = useNavigation();
|
|
76
|
-
authProps = Object.assign({},authProps),
|
|
77
|
-
fabProps = defaultObj(fabProps);
|
|
78
|
-
authRequired = defaultBool(authProps.required,authRequired,false);
|
|
79
|
-
withDrawer = typeof withDrawer =='boolean'? withDrawer : authRequired;
|
|
80
|
-
if(allowDrawer === false){
|
|
81
|
-
withDrawer = false;
|
|
82
|
-
}
|
|
83
|
-
if(authRequired === false){
|
|
84
|
-
withFab = false;
|
|
85
|
-
}
|
|
86
|
-
if(typeof withFab !=='boolean'){
|
|
87
|
-
withFab = withDrawer;
|
|
88
|
-
}
|
|
89
|
-
React.useEffect(() => {
|
|
90
|
-
if((title||subtitle) && navigation && navigation.setOptions){
|
|
91
|
-
const appName = APP.getName().toUpperCase();
|
|
92
|
-
subtitle = React.getTextContent(subtitle);
|
|
93
|
-
let screenTitle = getDefaultTitle(title,true);
|
|
94
|
-
if(subtitle){
|
|
95
|
-
screenTitle += " | "+subtitle;
|
|
96
|
-
}
|
|
97
|
-
if(!screenTitle.toUpperCase().contains(appName)){
|
|
98
|
-
screenTitle+=" | "+appName;
|
|
99
|
-
}
|
|
100
|
-
navigation.setOptions({
|
|
101
|
-
...options,
|
|
102
|
-
appBarProps:{...options.appBarProps,...appBarProps,title,subtitle},
|
|
103
|
-
subtitle :subtitle,
|
|
104
|
-
title : screenTitle,
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
}, [title,subtitle]);
|
|
108
|
-
const Wrapper = modal ? Portal : React.Fragment;
|
|
109
|
-
const fab = withFab !== false ? <Fab
|
|
110
|
-
{...fabProps}
|
|
111
|
-
screenName={screenName}
|
|
112
|
-
/> : null;
|
|
113
|
-
return <Wrapper>
|
|
114
|
-
<Auth.Container {...authProps} required ={authRequired}>
|
|
115
|
-
{withStatusBar !== false ? <StatusBar/> : null}
|
|
116
|
-
<ErrorBoundary testID={testID+"_ScreenLayoutErrorBoundary"}>
|
|
117
|
-
<View testID={testID} {...containerProps} style={[styles.container,{backgroundColor},modal && styles.modal]}>
|
|
118
|
-
{appBar === false ? null : React.isValidElement(appBar)? state.AppBar : <AppBar testID={testID+'_AppBar'} {...appBarProps} backAction = {defaultVal(appBarProps.backAction,backAction)} elevation={defaultNumber(appBarProps.elevation,elevation)} withDrawer={withDrawer} options={options} ref={appBarRef} title={title} subtitle={subtitle}/>}
|
|
119
|
-
{withScrollView !== false ? (
|
|
120
|
-
<ScrollView
|
|
121
|
-
testID = {testID+'_ScreenContentScrollView'}
|
|
122
|
-
{...rest}
|
|
123
|
-
contentContainerStyle={[contentContainerStyle]}
|
|
124
|
-
style={[containerStyle,styles.container, style]}
|
|
125
|
-
>
|
|
126
|
-
{children}
|
|
127
|
-
{fab}
|
|
128
|
-
</ScrollView>
|
|
129
|
-
) : (
|
|
130
|
-
<View testID={testID+'_ScreenContent'} {...rest} style={[containerStyle,styles.wrapper,styles.container, style]}>
|
|
131
|
-
{children}
|
|
132
|
-
{fab}
|
|
133
|
-
</View>
|
|
134
|
-
)}
|
|
135
|
-
</View>
|
|
136
|
-
</ErrorBoundary>
|
|
137
|
-
</Auth.Container>
|
|
138
|
-
</Wrapper>
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const styles = StyleSheet.create({
|
|
142
|
-
container: {
|
|
143
|
-
flex: 1,
|
|
144
|
-
},
|
|
145
|
-
wrapper : {
|
|
146
|
-
flexDirection:'column',
|
|
147
|
-
/*flex : 1,
|
|
148
|
-
flexGrow : 1,
|
|
149
|
-
alignItems:'center'*/
|
|
150
|
-
},
|
|
151
|
-
modal : {
|
|
152
|
-
...StyleSheet.absoluteFillObject,
|
|
153
|
-
top : 0,
|
|
154
|
-
left:0,
|
|
155
|
-
flex:1,
|
|
156
|
-
width : '100%',
|
|
157
|
-
height : '100%'
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
MainScreenLayoutComponent.propTypes = {
|
|
162
|
-
children: PropTypes.any,
|
|
163
|
-
withScrollView : PropTypes.bool,
|
|
164
|
-
style:PropTypes.object,
|
|
165
|
-
appBarProps : PropTypes.object,
|
|
166
|
-
elevation : PropTypes.number,
|
|
167
|
-
//appBar : PropTypes.bool,
|
|
168
|
-
contentContainerStyle : PropTypes.object,
|
|
169
|
-
withFab : PropTypes.bool,
|
|
170
|
-
withDrawer : PropTypes.bool,//si l'on doit afficher un drawer dans le contenu
|
|
171
|
-
fabProps : PropTypes.object,
|
|
8
|
+
export default function MainScreenComponent(props){
|
|
9
|
+
return <ScreenWithOrWithoutAuthContainer
|
|
10
|
+
{...props}
|
|
11
|
+
renderChildren = {({containerProps,children})=>{
|
|
12
|
+
return <Container {...containerProps}>
|
|
13
|
+
{children}
|
|
14
|
+
</Container>
|
|
15
|
+
}}
|
|
16
|
+
/>
|
|
172
17
|
}
|
|
@@ -0,0 +1,179 @@
|
|
|
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} from "$utils";
|
|
6
|
+
import ScrollView from '$ecomponents/ScrollView';
|
|
7
|
+
import View from "$ecomponents/View";
|
|
8
|
+
import { useNavigation,getScreenProps } from '$cnavigation';
|
|
9
|
+
import Fab from "$elayouts/Fab";
|
|
10
|
+
import APP from "$capp";
|
|
11
|
+
import AppBar,{createAppBarRef} from "$elayouts/AppBar";
|
|
12
|
+
import ErrorBoundary from "$ecomponents/ErrorBoundary";
|
|
13
|
+
import Portal from "$ecomponents/Portal";
|
|
14
|
+
import theme from "$theme";
|
|
15
|
+
import StatusBar from "$ecomponents/StatusBar";
|
|
16
|
+
|
|
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
|
+
}
|
|
29
|
+
|
|
30
|
+
export default function MainScreenScreenWithOrWithoutAuthContainer(props) {
|
|
31
|
+
let {
|
|
32
|
+
children,
|
|
33
|
+
withScrollView = false,
|
|
34
|
+
withStatusBar = true,
|
|
35
|
+
style,
|
|
36
|
+
contentContainerStyle,
|
|
37
|
+
options,
|
|
38
|
+
backAction,
|
|
39
|
+
appBarProps,
|
|
40
|
+
authProps,
|
|
41
|
+
elevation,
|
|
42
|
+
withFab,
|
|
43
|
+
appBar,
|
|
44
|
+
authRequired,
|
|
45
|
+
withDrawer,
|
|
46
|
+
allowDrawer,
|
|
47
|
+
title,
|
|
48
|
+
subtitle,
|
|
49
|
+
modal,
|
|
50
|
+
fabProps,
|
|
51
|
+
screenName,
|
|
52
|
+
containerProps,
|
|
53
|
+
testID,
|
|
54
|
+
renderChildren,
|
|
55
|
+
...rest
|
|
56
|
+
} = getScreenProps(props);
|
|
57
|
+
const insets = useSafeAreaInsets();
|
|
58
|
+
testID = defaultStr(testID,"RN_MainScreenScreenWithOrWithoutAuthContainer")
|
|
59
|
+
containerProps = defaultObj(containerProps);
|
|
60
|
+
const backgroundColor = theme.colors.background;
|
|
61
|
+
const containerStyle = [
|
|
62
|
+
styles.container,
|
|
63
|
+
{
|
|
64
|
+
backgroundColor,
|
|
65
|
+
paddingBottom: insets.bottom,
|
|
66
|
+
paddingLeft: insets.left,
|
|
67
|
+
paddingRight: insets.right,
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
options = defaultObj(options);
|
|
71
|
+
appBarProps = defaultObj(appBarProps)
|
|
72
|
+
title = defaultVal(appBarProps.title,options.title,title);
|
|
73
|
+
subtitle = defaultVal(appBarProps.subtitle,options.subtitle,subtitle);
|
|
74
|
+
const appBarRef = createAppBarRef();
|
|
75
|
+
const navigation = useNavigation();
|
|
76
|
+
authProps = Object.assign({},authProps),
|
|
77
|
+
fabProps = defaultObj(fabProps);
|
|
78
|
+
authRequired = defaultBool(authProps.required,authRequired,false);
|
|
79
|
+
withDrawer = typeof withDrawer =='boolean'? withDrawer : authRequired;
|
|
80
|
+
if(allowDrawer === false){
|
|
81
|
+
withDrawer = false;
|
|
82
|
+
}
|
|
83
|
+
if(authRequired === false){
|
|
84
|
+
withFab = false;
|
|
85
|
+
}
|
|
86
|
+
if(typeof withFab !=='boolean'){
|
|
87
|
+
withFab = withDrawer;
|
|
88
|
+
}
|
|
89
|
+
React.useEffect(() => {
|
|
90
|
+
if((title||subtitle) && navigation && navigation.setOptions){
|
|
91
|
+
const appName = APP.getName().toUpperCase();
|
|
92
|
+
subtitle = React.getTextContent(subtitle);
|
|
93
|
+
let screenTitle = getDefaultTitle(title,true);
|
|
94
|
+
if(subtitle){
|
|
95
|
+
screenTitle += " | "+subtitle;
|
|
96
|
+
}
|
|
97
|
+
if(!screenTitle.toUpperCase().contains(appName)){
|
|
98
|
+
screenTitle+=" | "+appName;
|
|
99
|
+
}
|
|
100
|
+
navigation.setOptions({
|
|
101
|
+
...options,
|
|
102
|
+
appBarProps:{...options.appBarProps,...appBarProps,title,subtitle},
|
|
103
|
+
subtitle :subtitle,
|
|
104
|
+
title : screenTitle,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}, [title,subtitle]);
|
|
108
|
+
const Wrapper = modal ? Portal : React.Fragment;
|
|
109
|
+
const fab = withFab !== false ? <Fab
|
|
110
|
+
{...fabProps}
|
|
111
|
+
screenName={screenName}
|
|
112
|
+
/> : null;
|
|
113
|
+
const child = <>
|
|
114
|
+
{withStatusBar !== false ? <StatusBar/> : null}
|
|
115
|
+
<ErrorBoundary testID={testID+"_ScreenLayoutErrorBoundary"}>
|
|
116
|
+
<View testID={testID} {...containerProps} style={[styles.container,{backgroundColor},modal && styles.modal]}>
|
|
117
|
+
{appBar === false ? null : React.isValidElement(appBar)? state.AppBar : <AppBar testID={testID+'_AppBar'} {...appBarProps} backAction = {defaultVal(appBarProps.backAction,backAction)} elevation={defaultNumber(appBarProps.elevation,elevation)} withDrawer={withDrawer} options={options} ref={appBarRef} title={title} subtitle={subtitle}/>}
|
|
118
|
+
{withScrollView !== false ? (
|
|
119
|
+
<ScrollView
|
|
120
|
+
testID = {testID+'_ScreenContentScrollView'}
|
|
121
|
+
{...rest}
|
|
122
|
+
contentContainerStyle={[contentContainerStyle]}
|
|
123
|
+
style={[containerStyle,styles.container, style]}
|
|
124
|
+
>
|
|
125
|
+
{children}
|
|
126
|
+
{fab}
|
|
127
|
+
</ScrollView>
|
|
128
|
+
) : (
|
|
129
|
+
<View testID={testID+'_ScreenContent'} {...rest} style={[containerStyle,styles.wrapper,styles.container, style]}>
|
|
130
|
+
{children}
|
|
131
|
+
{fab}
|
|
132
|
+
</View>
|
|
133
|
+
)}
|
|
134
|
+
</View>
|
|
135
|
+
</ErrorBoundary>
|
|
136
|
+
</>
|
|
137
|
+
return <Wrapper>
|
|
138
|
+
{renderChildren({
|
|
139
|
+
containerProps : {
|
|
140
|
+
...authProps,
|
|
141
|
+
required : authRequired,
|
|
142
|
+
},
|
|
143
|
+
children : child,
|
|
144
|
+
})}
|
|
145
|
+
</Wrapper>
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const styles = StyleSheet.create({
|
|
149
|
+
container: {
|
|
150
|
+
flex: 1,
|
|
151
|
+
},
|
|
152
|
+
wrapper : {
|
|
153
|
+
flexDirection:'column',
|
|
154
|
+
/*flex : 1,
|
|
155
|
+
flexGrow : 1,
|
|
156
|
+
alignItems:'center'*/
|
|
157
|
+
},
|
|
158
|
+
modal : {
|
|
159
|
+
...StyleSheet.absoluteFillObject,
|
|
160
|
+
top : 0,
|
|
161
|
+
left:0,
|
|
162
|
+
flex:1,
|
|
163
|
+
width : '100%',
|
|
164
|
+
height : '100%'
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
MainScreenScreenWithOrWithoutAuthContainer.propTypes = {
|
|
169
|
+
children: PropTypes.any,
|
|
170
|
+
withScrollView : PropTypes.bool,
|
|
171
|
+
style:PropTypes.object,
|
|
172
|
+
appBarProps : PropTypes.object,
|
|
173
|
+
elevation : PropTypes.number,
|
|
174
|
+
//appBar : PropTypes.bool,
|
|
175
|
+
contentContainerStyle : PropTypes.object,
|
|
176
|
+
withFab : PropTypes.bool,
|
|
177
|
+
withDrawer : PropTypes.bool,//si l'on doit afficher un drawer dans le contenu
|
|
178
|
+
fabProps : PropTypes.object,
|
|
179
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
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.
|
|
4
|
+
|
|
5
|
+
/*** afin d'éviter les redondances cycliques avec le module $loginComponent, ce composant doit être utiliser pour
|
|
6
|
+
* le rendu de tous les composants implémentés définis dans le fichier $loginComponent car ne necessite pas de test sur
|
|
7
|
+
le fait que l'utilisateur soit connecté où pas
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import ScreenWithOrWithoutAuthContainer from "./ScreenWithOrWithoutAuthContainer";
|
|
11
|
+
export default function ScreenWithoutAuthContainer(props){
|
|
12
|
+
return <ScreenWithOrWithoutAuthContainer
|
|
13
|
+
{...props}
|
|
14
|
+
renderChildren = {({children})=>{
|
|
15
|
+
return children
|
|
16
|
+
}}
|
|
17
|
+
/>
|
|
18
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Screen from "./Screen";
|
|
2
|
+
import ScreenWithoutAuthContainer from "./ScreenWithoutAuthContainer";
|
|
2
3
|
import FormData from "./FormData";
|
|
3
4
|
import List from "./FormData/List";
|
|
4
5
|
|
|
@@ -8,4 +9,4 @@ Screen.List = List;
|
|
|
8
9
|
|
|
9
10
|
export default Screen;
|
|
10
11
|
|
|
11
|
-
export {FormData,List};
|
|
12
|
+
export {FormData,List,ScreenWithoutAuthContainer};
|
|
@@ -45,9 +45,13 @@ const DrawerNavigator = React.forwardRef(({content,children,state,...props},ref)
|
|
|
45
45
|
React.useEffect(()=>{
|
|
46
46
|
if(prevIsLoggedIn === isLoggedIn) return;
|
|
47
47
|
navigate("Home");
|
|
48
|
-
},[isLoggedIn])
|
|
48
|
+
},[isLoggedIn]);
|
|
49
49
|
if(!isLoggedIn) {
|
|
50
|
-
return <Login withPortal
|
|
50
|
+
return <Login withPortal
|
|
51
|
+
onSuccess = {(data)=>{
|
|
52
|
+
setIsLoggedIn(true);
|
|
53
|
+
}}
|
|
54
|
+
/>
|
|
51
55
|
}
|
|
52
56
|
return <Drawer
|
|
53
57
|
isItemActive = {isItemActive}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
import {SIGN_IN} from "
|
|
2
|
+
import {SIGN_IN} from "$cauth/routes"
|
|
3
3
|
import Screen from "$escreen";
|
|
4
|
-
import {GROUP_NAMES} from "$escreens/utils";
|
|
5
4
|
import Login from "$eauth/Login";
|
|
6
5
|
import {getScreenProps} from "$cnavigation";
|
|
7
6
|
import {getTitle} from "./utils";
|
|
@@ -24,7 +23,7 @@ function AuthSignInScreen(_props){
|
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
AuthSignInScreen.screenName = SIGN_IN;
|
|
27
|
-
AuthSignInScreen.
|
|
26
|
+
AuthSignInScreen.authRequired = false;
|
|
28
27
|
AuthSignInScreen.modal = true;
|
|
29
28
|
AuthSignInScreen.allowDrawer = false;
|
|
30
29
|
|
package/src/screens/index.js
CHANGED
|
@@ -12,7 +12,6 @@ export * from "./utils";
|
|
|
12
12
|
export const SCREEN_OPTIONS = {};
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
|
|
16
15
|
export const handleScreen = ({Screen,Factory,ModalFactory,result,useTheme,filter,index})=>{
|
|
17
16
|
result = defaultObj(result);
|
|
18
17
|
result.screens = defaultObj(result.screens);
|
|
@@ -41,9 +40,9 @@ export const handleScreen = ({Screen,Factory,ModalFactory,result,useTheme,filter
|
|
|
41
40
|
return null;
|
|
42
41
|
}
|
|
43
42
|
///le groupe d'écran par défaut
|
|
44
|
-
let groupName =
|
|
43
|
+
let groupName = Screen.Start ||Screen.start ? GROUP_NAMES.START : authRequired === false ? GROUP_NAMES.PUBLIC : GROUP_NAMES.PRIVATE;
|
|
45
44
|
if(!GROUP_NAMES[groupName]){
|
|
46
|
-
groupName = GROUP_NAMES.
|
|
45
|
+
groupName = GROUP_NAMES.PRIVATE;
|
|
47
46
|
}
|
|
48
47
|
if(!authRequired){
|
|
49
48
|
groupName = groupName || GROUP_NAMES.PUBLIC;
|
|
@@ -179,7 +178,7 @@ export const handleContent = ({screens,hasGetStarted,state,Factory})=>{
|
|
|
179
178
|
Object.map(screens,(screens,groupName)=>{
|
|
180
179
|
if(!Array.isArray(screens)) return null;
|
|
181
180
|
if(hasGetStarted === false){
|
|
182
|
-
if(groupName == GROUP_NAMES.
|
|
181
|
+
if(groupName == GROUP_NAMES.START){
|
|
183
182
|
content.push(<Factory.Group key={groupName}>
|
|
184
183
|
{screens}
|
|
185
184
|
</Factory.Group>)
|