@fto-consult/expo-ui 1.4.16 → 1.5.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.
- package/babel.config.alias.js +17 -0
- package/find-licenses.js +66 -44
- package/package.json +2 -2
- package/src/App.js +1 -1
- package/src/auth/Login.js +5 -3
- package/src/components/Dialog/Dialog.js +5 -4
- package/src/components/Logo/Logo.js +1 -1
- package/src/layouts/Screen/ScreenWithOrWithoutAuthContainer.js +3 -3
- package/src/navigation/Drawer/items/index.js +7 -4
- package/src/screens/Help/About.js +137 -0
- package/src/screens/Help/HashTag.js +61 -0
- package/src/screens/Help/PrivacyPolicy/Link.js +22 -0
- package/src/screens/Help/PrivacyPolicy/content.js +13 -0
- package/src/screens/Help/PrivacyPolicy/index.js +39 -0
- package/src/screens/Help/PrivacyPolicy/routes.js +1 -0
- package/src/screens/Help/PrivacyPolicy/title.js +1 -0
- package/src/screens/Help/TermsOfUses/Link.js +12 -0
- package/src/screens/Help/TermsOfUses/content.js +13 -0
- package/src/screens/Help/TermsOfUses/index.js +41 -0
- package/src/screens/Help/TermsOfUses/routes.js +1 -0
- package/src/screens/Help/TermsOfUses/title.js +1 -0
- package/src/screens/Help/deviceProps.js +14 -0
- package/src/screens/Help/getDevicesInfos.js +31 -0
- package/src/screens/Help/getReleaseText.js +10 -0
- package/src/screens/Help/index.js +8 -0
- package/src/screens/mainScreens.js +2 -0
package/babel.config.alias.js
CHANGED
|
@@ -81,5 +81,22 @@ module.exports = (opts)=>{
|
|
|
81
81
|
}
|
|
82
82
|
///le chemin racine du projet expo-ui
|
|
83
83
|
r["$expo-ui-root-path"] = r["$expo-ui-root"]= path.resolve(expo,"..");
|
|
84
|
+
|
|
85
|
+
const HelpScreen = path.resolve(r["$escreens"],"Help");
|
|
86
|
+
/*** alias des termsOfUses */
|
|
87
|
+
if(!r.$TermsOfUses){
|
|
88
|
+
r.$TermsOfUses = path.resolve(HelpScreen,"TermsOfUses","content")
|
|
89
|
+
}
|
|
90
|
+
/*** alias des privacyPolicy */
|
|
91
|
+
if(!r.$PrivacyPolicy){
|
|
92
|
+
r.$PrivacyPolicy = path.resolve(HelpScreen,"PrivacyPolicy","content")
|
|
93
|
+
}
|
|
94
|
+
///on génère les librairies open sources utilisées par l'application
|
|
95
|
+
const root = path.resolve(r.$src,"..");
|
|
96
|
+
const outputPath = path.resolve(HelpScreen,"openLibraries.js");
|
|
97
|
+
require("./find-licenses")({
|
|
98
|
+
paths : [root,r["$expo-ui-root-path"]],
|
|
99
|
+
outputPath
|
|
100
|
+
});
|
|
84
101
|
return r;
|
|
85
102
|
}
|
package/find-licenses.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
-
const dir = path.resolve(__dirname);
|
|
3
|
-
let filePath = path.resolve(dir,"src/help/openLibraries.js")
|
|
4
2
|
let isObj = x => x && typeof x == 'object';
|
|
5
3
|
const fs = require('fs')
|
|
6
4
|
let openLibraries = {};
|
|
@@ -15,57 +13,81 @@ function isValidUrl(str) {
|
|
|
15
13
|
return !!pattern.test(str);
|
|
16
14
|
}
|
|
17
15
|
|
|
18
|
-
const loopPackages = (packages,
|
|
16
|
+
const loopPackages = (packages,projectPath)=>{
|
|
19
17
|
if(!isObj(packages)) return;
|
|
20
|
-
let p = path.resolve(
|
|
18
|
+
let p = path.resolve(projectPath,"node_modules");
|
|
21
19
|
for(let i in packages){
|
|
22
20
|
let packagePath = path.resolve(p,i,"package.json");
|
|
23
21
|
if(fs.existsSync(packagePath)){
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
22
|
+
try {
|
|
23
|
+
let package = require(packagePath);
|
|
24
|
+
if(!isObj(package) || !package.name) return;
|
|
25
|
+
let op = {};
|
|
26
|
+
openLibraries[package.name] = op;
|
|
27
|
+
if(package.version){
|
|
28
|
+
op.version = package.version;
|
|
29
|
+
}
|
|
30
|
+
if(isValidUrl(package.homepage)){
|
|
31
|
+
op.url = package.homepage
|
|
32
|
+
} else if(isValidUrl(package.repository)) {
|
|
33
|
+
op.url = package.repository;
|
|
34
|
+
} else if(isObj(package.repository) && package.repository.url){
|
|
35
|
+
op.url = package.repository.url;
|
|
36
|
+
}
|
|
37
|
+
if(package.license || package.licence){
|
|
38
|
+
op.license = typeof package.license =="string"? package.license : typeof package.licence =="string"? package.licence : "";
|
|
39
|
+
}
|
|
40
|
+
} catch(e){
|
|
41
|
+
console.log(e," looking for package dep")
|
|
40
42
|
}
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
}
|
|
44
46
|
|
|
45
|
-
const findLicences = (
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
const findLicences = (projectPath)=> {
|
|
48
|
+
if(projectPath && typeof projectPath =='string' && fs.existsSync(projectPath)){
|
|
49
|
+
const packagePath = path.resolve(projectPath,"package.json");
|
|
50
|
+
if(fs.existsSync(packagePath)){
|
|
51
|
+
const packages = require(packagePath);
|
|
52
|
+
if(isObj(packages)){
|
|
53
|
+
loopPackages(packages.devDependencies,projectPath);
|
|
54
|
+
loopPackages(packages.dependencies,projectPath);
|
|
55
|
+
}
|
|
52
56
|
}
|
|
53
57
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
58
|
+
}
|
|
59
|
+
module.exports = (options)=>{
|
|
60
|
+
options = typeof options =='string'? {path:options} : typeof options =='object' && options ? options : {};
|
|
61
|
+
if(!options || typeof options !='object'){
|
|
62
|
+
options = {};
|
|
63
|
+
}
|
|
64
|
+
const {outputPath} = options;
|
|
65
|
+
const outputDir = outputPath && typeof outputPath =='string' && path.dirname(outputPath) || '';
|
|
66
|
+
if(outputDir && fs.existsSync(outputDir)){
|
|
67
|
+
openLibraries = {};
|
|
68
|
+
if(Array.isArray(options.paths)){
|
|
69
|
+
options.paths.map((p)=>{
|
|
70
|
+
if(p && typeof p =='string' && fs.existsSync(p)){
|
|
71
|
+
findLicences(p)
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
} else {
|
|
75
|
+
findLicences(options.path)
|
|
76
|
+
}
|
|
77
|
+
const s = Object.keys(openLibraries).sort((a,b)=>{
|
|
78
|
+
if (a.toLowerCase() < b.toLowerCase()) return -1;
|
|
79
|
+
if (a.toLowerCase() > b.toLowerCase()) return 1;
|
|
80
|
+
return 0;
|
|
81
|
+
});
|
|
82
|
+
const content = {};
|
|
83
|
+
for(let i in s){
|
|
84
|
+
content[s[i]] = openLibraries[s[i]]
|
|
85
|
+
}
|
|
86
|
+
fs.writeFileSync(outputPath, "module.exports = "+JSON.stringify(content)+";");
|
|
87
|
+
} else {
|
|
88
|
+
return ({
|
|
89
|
+
error : true,
|
|
90
|
+
message : "Le chemin du fichier output est innexistant. veuillez spécifier un chemin de fichier existant dans lequel seront générées les licences utilisées pour le développement de l'application"
|
|
91
|
+
});
|
|
68
92
|
}
|
|
69
|
-
|
|
70
|
-
fs.writeFileSync(filePath, content)
|
|
71
|
-
});
|
|
93
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fto-consult/expo-ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.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
|
"@expo/html-elements": "^0.2.0",
|
|
62
62
|
"@expo/metro-config": "^0.4.0",
|
|
63
63
|
"@expo/webpack-config": "^0.17.2",
|
|
64
|
-
"@fto-consult/common": "^1.7.
|
|
64
|
+
"@fto-consult/common": "^1.7.15",
|
|
65
65
|
"@gorhom/portal": "^1.0.14",
|
|
66
66
|
"@react-native-async-storage/async-storage": "~1.17.3",
|
|
67
67
|
"@react-native-community/datetimepicker": "6.2.0",
|
package/src/App.js
CHANGED
|
@@ -90,7 +90,7 @@ setDeviceIdRef.current = ()=>{
|
|
|
90
90
|
showPrompt({
|
|
91
91
|
title : 'ID unique pour l\'appareil',
|
|
92
92
|
maxLength : 30,
|
|
93
|
-
defaultValue : appConfig.
|
|
93
|
+
defaultValue : appConfig.getDeviceId(),
|
|
94
94
|
yes : 'Définir',
|
|
95
95
|
placeholder : isMobileNative()? "":'Entrer une valeur unique sans espace SVP',
|
|
96
96
|
no : 'Annuler',
|
package/src/auth/Login.js
CHANGED
|
@@ -19,6 +19,7 @@ import ScreenWithoutAuthContainer from "$escreen/ScreenWithoutAuthContainer";
|
|
|
19
19
|
import {getTitle} from "$escreens/Auth/utils";
|
|
20
20
|
import {isWeb} from "$cplatform";
|
|
21
21
|
import ProviderSelector from "./ProviderSelector";
|
|
22
|
+
import { ScrollView } from "react-native";
|
|
22
23
|
|
|
23
24
|
import getLoginProps from "$getLoginProps";
|
|
24
25
|
const getProps = typeof getLoginProps =='function'? getLoginProps : x=>null;
|
|
@@ -34,7 +35,6 @@ export default function LoginComponent(props){
|
|
|
34
35
|
const previousButtonRef = React.useRef(null);
|
|
35
36
|
const dialogProviderRef = React.useRef(null);
|
|
36
37
|
const backgroundColor = theme.colors.surface;
|
|
37
|
-
const Wrapper = withPortal ? ScreenWithoutAuthContainer : View;
|
|
38
38
|
const _getForm = x=> getForm(formName);
|
|
39
39
|
const isMounted = React.useIsMounted();
|
|
40
40
|
|
|
@@ -88,6 +88,7 @@ export default function LoginComponent(props){
|
|
|
88
88
|
},[withPortal])
|
|
89
89
|
const {header,children,initialize,contentTop,data:loginData,canGoToNext,keyboardEvents,onSuccess:onLoginSuccess,mutateData,canSubmit:canSubmitForm,onStepChange,...loginProps} = defaultObj(getProps({
|
|
90
90
|
...state,
|
|
91
|
+
withScrollView:customerWithScrollView,
|
|
91
92
|
setState,
|
|
92
93
|
state,
|
|
93
94
|
showError : notifyUser,
|
|
@@ -170,8 +171,9 @@ export default function LoginComponent(props){
|
|
|
170
171
|
setState({...state,step:step+1,data})
|
|
171
172
|
}
|
|
172
173
|
}
|
|
173
|
-
|
|
174
|
-
const
|
|
174
|
+
const withScrollView = typeof customerWithScrollView =='boolean'? customerWithScrollView : true;
|
|
175
|
+
const Wrapper = withPortal ? ScreenWithoutAuthContainer : withScrollView ? ScrollView: View;
|
|
176
|
+
const wrapperProps = withPortal ? {appBarProps,authRequired:false,title:loginTitle,withScrollView} : { style:styles.wrapper};
|
|
175
177
|
return <Wrapper testID = {testID+"_Wrapper" }{...wrapperProps}>
|
|
176
178
|
<DialogProvider ref={dialogProviderRef}/>
|
|
177
179
|
<Surface style={[styles.container,{backgroundColor}]} testID={testID}>
|
|
@@ -12,7 +12,7 @@ import AppBarDialog from "./AppBarDialog";
|
|
|
12
12
|
import DialogActions from "./DialogActions";
|
|
13
13
|
import DialogTitle from './DialogTitle';
|
|
14
14
|
import {MAX_WIDTH,SCREEN_INDENT,MIN_HEIGHT} from "./utils";
|
|
15
|
-
import {isMobileOrTabletMedia} from "$cplatform/dimensions";
|
|
15
|
+
import {isMobileOrTabletMedia,isMobileMedia} from "$cplatform/dimensions";
|
|
16
16
|
import Platform,{isMobileNative} from "$cplatform";
|
|
17
17
|
import Portal from "$ecomponents/Portal";
|
|
18
18
|
import Icon,{BACK_ICON} from "$ecomponents/Icon";
|
|
@@ -162,13 +162,14 @@ const DialogComponent = React.forwardRef((props,ref)=>{
|
|
|
162
162
|
const testID = defaultStr(modalProps.testID,"RN_DialogComponent");
|
|
163
163
|
const maxHeight = getMaxHeight(),maxWidth = getMaxWidth();
|
|
164
164
|
const backgroundColor = theme.surfaceBackgroundColor;
|
|
165
|
-
borderRadius = fullScreen
|
|
165
|
+
borderRadius = fullScreen || !(isMobileNative() || isMobileMedia()) || isPreloader ? 0 : typeof borderRadius =='number'? borderRadius : 5*theme.roundness;
|
|
166
166
|
const fullScreenStyle = fullScreen ? {width:dimensions.width,height:dimensions.height,marginHorizontal:0,paddingHorizontal:0}: {
|
|
167
167
|
maxWidth,
|
|
168
168
|
maxHeight,
|
|
169
169
|
borderRadius,
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
paddingLeft : borderRadius,
|
|
171
|
+
paddingRight : borderRadius,
|
|
172
|
+
paddingVertical : borderRadius?10:0,
|
|
172
173
|
};
|
|
173
174
|
const alertContentStyle = isAlert ? {paddingHorizontal:15} : null;
|
|
174
175
|
content = <Surface ref={contentRef} testID = {testID+"_Content11"} {...contentProps} style={[fullScreen? {flex:1}:{maxWidth,maxHeight:maxHeight-Math.min(SCREEN_INDENT*2+50,100)},isPreloader && {paddingHorizontal:10},{backgroundColor},alertContentStyle,contentProps.style]}>
|
|
@@ -11,7 +11,7 @@ import APP from "$capp";
|
|
|
11
11
|
import AppBar,{createAppBarRef} from "$elayouts/AppBar";
|
|
12
12
|
import ErrorBoundary from "$ecomponents/ErrorBoundary";
|
|
13
13
|
import Portal from "$ecomponents/Portal";
|
|
14
|
-
import theme from "$theme";
|
|
14
|
+
import theme,{StyleProp} from "$theme";
|
|
15
15
|
import StatusBar from "$ecomponents/StatusBar";
|
|
16
16
|
|
|
17
17
|
const getDefaultTitle = (nTitle,returnStr)=>{
|
|
@@ -168,11 +168,11 @@ const styles = StyleSheet.create({
|
|
|
168
168
|
MainScreenScreenWithOrWithoutAuthContainer.propTypes = {
|
|
169
169
|
children: PropTypes.any,
|
|
170
170
|
withScrollView : PropTypes.bool,
|
|
171
|
-
style:
|
|
171
|
+
style:StyleProp,
|
|
172
172
|
appBarProps : PropTypes.object,
|
|
173
173
|
elevation : PropTypes.number,
|
|
174
174
|
//appBar : PropTypes.bool,
|
|
175
|
-
contentContainerStyle :
|
|
175
|
+
contentContainerStyle : StyleProp,
|
|
176
176
|
withFab : PropTypes.bool,
|
|
177
177
|
withDrawer : PropTypes.bool,//si l'on doit afficher un drawer dans le contenu
|
|
178
178
|
fabProps : PropTypes.object,
|
|
@@ -7,6 +7,7 @@ import "$cutils";
|
|
|
7
7
|
import APP from "$capp";
|
|
8
8
|
///les items du drawer
|
|
9
9
|
import items from "$drawerItems";
|
|
10
|
+
import { screenName as aboutScreenName} from "$escreens/Help/About";
|
|
10
11
|
|
|
11
12
|
export const getItems = (force)=>{
|
|
12
13
|
const name = APP.getName();
|
|
@@ -25,16 +26,18 @@ export const getItems = (force)=>{
|
|
|
25
26
|
r.push(item);
|
|
26
27
|
}
|
|
27
28
|
})
|
|
29
|
+
r.push({divider:true});
|
|
28
30
|
r.push({
|
|
29
31
|
key : 'dataHelp',
|
|
30
32
|
label : 'Aide',
|
|
31
33
|
section : true,
|
|
32
34
|
divider : false,
|
|
33
35
|
items : [
|
|
34
|
-
|
|
35
|
-
icon : '
|
|
36
|
-
label :
|
|
37
|
-
|
|
36
|
+
{
|
|
37
|
+
icon : 'help',
|
|
38
|
+
label : 'A propos de '+name,
|
|
39
|
+
routeName : aboutScreenName,
|
|
40
|
+
}
|
|
38
41
|
]
|
|
39
42
|
});
|
|
40
43
|
return r;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import Logo from "$ecomponents/Logo";
|
|
2
|
+
import Link from "$ecomponents/Link";
|
|
3
|
+
import Icon from "$ecomponents/Icon";
|
|
4
|
+
import Divider from "$ecomponents/Divider";
|
|
5
|
+
import PrivacyPolicyLink from "./PrivacyPolicy/Link";
|
|
6
|
+
import TermsOfUsesLink from "./TermsOfUses/Link";
|
|
7
|
+
import {isNativeDesktop,isAndroid,isIos} from "$platform";
|
|
8
|
+
import Expandable from "$ecomponents/Expandable";
|
|
9
|
+
import React from "$react";
|
|
10
|
+
import Screen from "$screen";
|
|
11
|
+
import getDevicesInfos from "./getDevicesInfos";
|
|
12
|
+
import View from "$ecomponents/View";
|
|
13
|
+
import Label from "$ecomponents/Label";
|
|
14
|
+
import {defaultStr} from "$utils";
|
|
15
|
+
import theme from "$theme";
|
|
16
|
+
import APP from "$app";
|
|
17
|
+
import AutoLink from "$ecomponents/AutoLink";
|
|
18
|
+
import Grid from "$ecomponents/Grid";
|
|
19
|
+
import getReleaseText from "./getReleaseText";
|
|
20
|
+
import appConfig from "$capp/config";
|
|
21
|
+
let openLibraries = null;
|
|
22
|
+
try {
|
|
23
|
+
openLibraries = require("./openLibraries");
|
|
24
|
+
} catch{
|
|
25
|
+
openLibraries = null;
|
|
26
|
+
}
|
|
27
|
+
export default function HelpScreen(props){
|
|
28
|
+
const deviceInfo = getDevicesInfos();
|
|
29
|
+
let icon = undefined, iconText = undefined;
|
|
30
|
+
let device = APP.DEVICE;
|
|
31
|
+
let operatingSystem = defaultStr(device.operatingSystem).toLowerCase();
|
|
32
|
+
let isLaptop = device.isLaptop;
|
|
33
|
+
if(isLaptop){
|
|
34
|
+
icon = "laptop";
|
|
35
|
+
iconText = "un ordinateur portable"
|
|
36
|
+
}
|
|
37
|
+
if(isAndroid()){
|
|
38
|
+
icon = "android";
|
|
39
|
+
iconText = "un téléphone Android";
|
|
40
|
+
} else if(isIos()){
|
|
41
|
+
icon = "apple-ios";
|
|
42
|
+
iconText = "un iphone";
|
|
43
|
+
} else if(isNativeDesktop() && operatingSystem){
|
|
44
|
+
if(!isLaptop){
|
|
45
|
+
icon = "desktop-classic";
|
|
46
|
+
iconText = "un ordinateur de bureau";
|
|
47
|
+
}
|
|
48
|
+
if(operatingSystem.contains("linux")){
|
|
49
|
+
if(!isLaptop){
|
|
50
|
+
icon = "linux";
|
|
51
|
+
}
|
|
52
|
+
iconText += " sur lequel est installé une distribution linux";
|
|
53
|
+
} else if(operatingSystem.contains("windows")){
|
|
54
|
+
icon = isLaptop ? "laptop" : "windows";
|
|
55
|
+
iconText += (isLaptop?" window":"")+ " sur lequel est installé le système windows";
|
|
56
|
+
} else {
|
|
57
|
+
icon = isLaptop ? "laptop" : "desktop-classic";
|
|
58
|
+
iconText += " Mac os";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const gridPadding = 5;
|
|
62
|
+
const gridStyles = [{width:40,padding:gridPadding},{width:'60%',padding:gridPadding},{width:60,padding:gridPadding},{width:60,padding:gridPadding}];
|
|
63
|
+
const borderStyle = {borderColor:theme.colors.divider,borderWidth:1,justifyContent:'space-between'};
|
|
64
|
+
const testID = defaultStr(props.testID,"RN_HelpAboutScreenComponent")
|
|
65
|
+
return <Screen withScrollView title={title} {...props} testID={testID+"_Screen"}>
|
|
66
|
+
<View testID={testID+"_Container"} style={[theme.styles.alignItemsCenter,theme.styles.justifyContentCenter,theme.styles.flex1,theme.styles.w100,theme.styles.p1]}>
|
|
67
|
+
<Logo testID={testID+"_Logo"} style={{marginRight:10}}/>
|
|
68
|
+
{getReleaseText()}
|
|
69
|
+
<Divider testID={testID+"_Divider1"} style={[theme.styles.mv1]}/>
|
|
70
|
+
<View testID={testID+"_IconText"} style = {[theme.styles.row]}>
|
|
71
|
+
{icon && iconText ? <Icon name={icon} primary title={"Ce périférique est "+iconText} /> : null}
|
|
72
|
+
</View>
|
|
73
|
+
<View testID={testID+"_DeviceInfos"} style={theme.styles.pb2}>
|
|
74
|
+
{deviceInfo}
|
|
75
|
+
</View>
|
|
76
|
+
<View testID={testID}>
|
|
77
|
+
<Label testID={testID+"_CopyRight"} style={theme.styles.p05}>{appConfig.copyright}</Label>
|
|
78
|
+
{appConfig.devMail? <AutoLink testID={testID+"_Email"} style={[theme.styles.row]}
|
|
79
|
+
email = {appConfig.devMail}
|
|
80
|
+
>
|
|
81
|
+
<Label>Nous contacter : </Label>
|
|
82
|
+
<Label primary textBold>{appConfig.devMail}</Label>
|
|
83
|
+
</AutoLink>:null}
|
|
84
|
+
<TermsOfUsesLink testID={testID+"_TemrsOfUsesLink"} style={theme.styles.mv05} children="CONTRAT DE LICENCE."/>
|
|
85
|
+
<PrivacyPolicyLink testID={testID+"_PrivacyPolicyLink"} style={theme.styles.mv05} children="POLITIQUE DE CONFIDENTIALITE."/>
|
|
86
|
+
<Link routeName={"releaseNotes"}>
|
|
87
|
+
<Label primary textBold style={theme.styles.mv05} >{appConfig.name+", Notes de mise à jour."}</Label>
|
|
88
|
+
</Link>
|
|
89
|
+
</View>
|
|
90
|
+
{Object.size(openLibraries,true) ? <View style={[theme.styles.w100]}>
|
|
91
|
+
<Expandable
|
|
92
|
+
testID={testID+"_OpenLibraries"}
|
|
93
|
+
title = {"A propos des librairies tiers"}
|
|
94
|
+
titleProps = {{style:theme.styles.ph1}}
|
|
95
|
+
style = {{backgroundColor:'transparent'}}
|
|
96
|
+
>
|
|
97
|
+
<View testID={testID+"_OpenLibraries_Header"} style={[theme.styles.row,theme.styles.flexWrap]}>
|
|
98
|
+
<Label testID={testID+"_OpenLibraries_HeaderLabel"} primary textBold>{appConfig.name+" "}</Label>
|
|
99
|
+
<Label>est bâti sur un ensemble d'outils et librairies open Source</Label>
|
|
100
|
+
</View>
|
|
101
|
+
<View testID={testID+"_OpenLibrariesContent"} style={[theme.styles.w100,theme.styles.pv1]}>
|
|
102
|
+
<Grid.Row style={borderStyle}>
|
|
103
|
+
<Label style={gridStyles[0]} textBold>#</Label>
|
|
104
|
+
<Label style={gridStyles[1]} textBold>Librairie/Outil</Label>
|
|
105
|
+
<Label style={gridStyles[2]} textBold>Version</Label>
|
|
106
|
+
<Label style={gridStyles[3]} textBold>Licence</Label>
|
|
107
|
+
</Grid.Row>
|
|
108
|
+
{Object.mapToArray(openLibraries,(lib,i,_i)=>{
|
|
109
|
+
return <Grid.Row key={i} style={borderStyle}>
|
|
110
|
+
<Label style={gridStyles[0]}>
|
|
111
|
+
{_i.formatNumber()}
|
|
112
|
+
</Label>
|
|
113
|
+
<AutoLink style={gridStyles[1]} url={lib.url}>
|
|
114
|
+
<Label splitText>{i}</Label>
|
|
115
|
+
</AutoLink>
|
|
116
|
+
<AutoLink style={gridStyles[2]}>
|
|
117
|
+
<Label splitText numberOfLines={2}>{defaultStr(lib.version)}</Label>
|
|
118
|
+
</AutoLink>
|
|
119
|
+
<AutoLink url={lib.licenseUrl} style={gridStyles[3]}>
|
|
120
|
+
<Label splitText>{lib.license}</Label>
|
|
121
|
+
</AutoLink>
|
|
122
|
+
</Grid.Row>
|
|
123
|
+
})}
|
|
124
|
+
</View>
|
|
125
|
+
</Expandable>
|
|
126
|
+
</View>: null}
|
|
127
|
+
</View>
|
|
128
|
+
</Screen>
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export const title = HelpScreen.title = "A propos";
|
|
132
|
+
|
|
133
|
+
export const screenName = HelpScreen.screenName = "Help/About";
|
|
134
|
+
|
|
135
|
+
HelpScreen.AuthRequired = false;
|
|
136
|
+
|
|
137
|
+
HelpScreen.Modal = true;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import templates from "$ecomponents/Form/Fields/sprintfSelectors";
|
|
2
|
+
import Icon from "$ecomponents/Icon";
|
|
3
|
+
import View from "$ecomponents/View";
|
|
4
|
+
import Label from "$ecomponents/Label";
|
|
5
|
+
import Screen from "$screen";
|
|
6
|
+
import Br from "$ecomponents/Br";
|
|
7
|
+
import Grid from "$ecomponents/Grid";
|
|
8
|
+
import theme from "$theme";
|
|
9
|
+
|
|
10
|
+
export default function HashTagHelpScreen (props){
|
|
11
|
+
const icon = <Icon name="format-header-pound" primary textBold cursorPointer/>;
|
|
12
|
+
const rowStyle = [{width:150}];
|
|
13
|
+
const borderStyle = {borderWidth:1,borderColor:theme.colors.divider};
|
|
14
|
+
return <Screen withScrollView {...props}>
|
|
15
|
+
<View style={[theme.styles.p1,theme.styles.w100]}>
|
|
16
|
+
<Label primary textBold>
|
|
17
|
+
Rubrique d'aide SALITE relative aux HashTags.
|
|
18
|
+
</Label>
|
|
19
|
+
<View>
|
|
20
|
+
<Label>
|
|
21
|
+
Les hashtag permettent de créer des liens vers les documents de stocks, ventes, achats, .... dans un contenu de type chaine de caractère.
|
|
22
|
+
</Label>
|
|
23
|
+
<Label>
|
|
24
|
+
Ils peuvent être insérés dans de tout type de champ portant l'icone ci-dessous à droite
|
|
25
|
+
</Label>
|
|
26
|
+
{icon}
|
|
27
|
+
<Label>
|
|
28
|
+
A chaque fois que vous rencontrez un champ de texte portant cette icone, il est possible d'insérer un hastag lors de la saisie des informations du champ de type texte.
|
|
29
|
+
Pour insérer un hastag, il suffit tout simplement d'insérer dans le texte l'une des valeur du code situé dans le tableau suivant et de cliquer
|
|
30
|
+
sur l'icone en question où d'éffectuer la combinaison des touches clavier : ctr+m
|
|
31
|
+
</Label>
|
|
32
|
+
<Br/>
|
|
33
|
+
<Label primary textBold>Liste des code hashtag suppportés par l'application</Label>
|
|
34
|
+
<Br/>
|
|
35
|
+
</View>
|
|
36
|
+
<View style={[theme.styles.w100]}>
|
|
37
|
+
<Grid.Row style={[borderStyle]}>
|
|
38
|
+
<Label textBold style={[rowStyle[0]]}>Code</Label>
|
|
39
|
+
<Label textBold>Signification</Label>
|
|
40
|
+
</Grid.Row>
|
|
41
|
+
{
|
|
42
|
+
Object.mapToArray(templates,(t,i)=>{
|
|
43
|
+
if(isObj(t)){
|
|
44
|
+
t = defaultStr(t.desc,t.title);
|
|
45
|
+
}
|
|
46
|
+
if(!isNonNullString(t)) return null;
|
|
47
|
+
return <Grid.Row style={[borderStyle]} key={i}>
|
|
48
|
+
<Label primary textBold style={[rowStyle[0]]}>{i}</Label>
|
|
49
|
+
<Label splitText numberOfLines={3}>{t}</Label>
|
|
50
|
+
</Grid.Row>
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
</View>
|
|
54
|
+
</View>
|
|
55
|
+
</Screen>
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const screenName = HashTagHelpScreen.screenName = "Help/Hashtag";
|
|
59
|
+
export const title = HashTagHelpScreen.title = "Hashtags : Aide".toUpperCase();
|
|
60
|
+
|
|
61
|
+
HashTagHelpScreen.Modal = true;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import Link from "$ecomponents/Link";
|
|
2
|
+
import {PRIVACY_POLICY} from "./routes";
|
|
3
|
+
import theme from "$theme";
|
|
4
|
+
import {StyleSheet} from "react-native";
|
|
5
|
+
import title from "./title";
|
|
6
|
+
import {defaultObj} from "$utils";
|
|
7
|
+
import Label from "$ecomponents/Label";
|
|
8
|
+
export default function(props){
|
|
9
|
+
const {style,...rest} = props;
|
|
10
|
+
return <Link routeName={PRIVACY_POLICY}>
|
|
11
|
+
<Label {...defaultObj(rest)} style={[{color:theme.colors.primary},styles.content,style]}>
|
|
12
|
+
{props.children || title}
|
|
13
|
+
</Label>
|
|
14
|
+
</Link>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const styles = StyleSheet.create({
|
|
18
|
+
content : {
|
|
19
|
+
textDecorationLine:'underline',
|
|
20
|
+
fontWeight : 'bold',
|
|
21
|
+
}
|
|
22
|
+
})
|
|
@@ -0,0 +1,13 @@
|
|
|
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
|
+
import Label from "$components/Label";
|
|
6
|
+
|
|
7
|
+
export default function ContentPrivacy (){
|
|
8
|
+
return <Label primary style={{fontSize:15,fontWeight:'bold',padding:10}}>
|
|
9
|
+
Pour définir modifier le contenu de la police de sécurité, il suffit de déclarer dans les alias, l'alias
|
|
10
|
+
$PrivacyPolicy prointant dans un fichier javascript dans lequel vous exportez par défaut, soit un composant React
|
|
11
|
+
où encore un élément react valide, qui remplacera ledit contenu
|
|
12
|
+
</Label>
|
|
13
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {PRIVACY_POLICY} from "./routes";
|
|
2
|
+
import title from "./title"
|
|
3
|
+
import Screen from "$screen";
|
|
4
|
+
import Link from "./Link";
|
|
5
|
+
import Content from "$PrivacyPolicy";
|
|
6
|
+
import {getScreenProps} from "$cnavigation";
|
|
7
|
+
import React from "$react";
|
|
8
|
+
|
|
9
|
+
export default function PrivacyPolicy(p){
|
|
10
|
+
const props = getScreenProps(p);
|
|
11
|
+
return <Screen
|
|
12
|
+
{...props}
|
|
13
|
+
withDrawer = {false}
|
|
14
|
+
appBarProps = {extendObj({},{
|
|
15
|
+
backAction : false,
|
|
16
|
+
title,
|
|
17
|
+
actions : [{
|
|
18
|
+
text : "Accepter",
|
|
19
|
+
icon : "check",
|
|
20
|
+
onPress : ({goBack})=>{
|
|
21
|
+
goBack && goBack();
|
|
22
|
+
}
|
|
23
|
+
}],
|
|
24
|
+
}, props.appBarProps)}
|
|
25
|
+
>
|
|
26
|
+
{React.isComponent(Content)? <Content {...props}/> : React.isValidElement(Content)? Content : null}
|
|
27
|
+
</Screen>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
PrivacyPolicy.screenName = PRIVACY_POLICY;
|
|
32
|
+
|
|
33
|
+
PrivacyPolicy.authRequired = false;
|
|
34
|
+
|
|
35
|
+
PrivacyPolicy.Modal = true;
|
|
36
|
+
|
|
37
|
+
PrivacyPolicy.title = title;
|
|
38
|
+
|
|
39
|
+
PrivacyPolicy.Link = Link;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const PRIVACY_POLICY = "PRIVACY_POLICY";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default 'POLITIQUE DE CONFIDENTIALITE';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Link from "$ecomponents/Link";
|
|
2
|
+
import {TERMS_OF_USES} from "./routes";
|
|
3
|
+
import theme from "$theme";
|
|
4
|
+
import title from "./title";
|
|
5
|
+
import Label from "$ecomponents/Label";
|
|
6
|
+
export default function(props){
|
|
7
|
+
return <Link routeName={TERMS_OF_USES}>
|
|
8
|
+
<Label {...props} style={[props.style,{color:theme.colors.primary,fontWeight:'bold',textDecorationLine:'underline'}]}>
|
|
9
|
+
{props.children || title}
|
|
10
|
+
</Label>
|
|
11
|
+
</Link>
|
|
12
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
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
|
+
import Label from "$components/Label";
|
|
6
|
+
|
|
7
|
+
export default function ContentTermsOfUses (){
|
|
8
|
+
return <Label primary style={{fontSize:15,fontWeight:'bold',padding:10}}>
|
|
9
|
+
Pour définir modifier le contenu de la police de sécurité, il suffit de déclarer dans les alias, l'alias
|
|
10
|
+
$TermsOfUses prointant dans un fichier javascript dans lequel vous exportez par défaut, soit un composant React
|
|
11
|
+
où encore un élément react valide, qui remplacera ledit contenu
|
|
12
|
+
</Label>
|
|
13
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {TERMS_OF_USES} from "./routes";
|
|
2
|
+
import title from "./title";
|
|
3
|
+
import Screen from "$screen";
|
|
4
|
+
import Link from "./Link";
|
|
5
|
+
import Content from "$TermsOfUses";
|
|
6
|
+
import {getScreenProps} from "$cnavigation";
|
|
7
|
+
import {extendObj} from "$utils";
|
|
8
|
+
import React from "$react";
|
|
9
|
+
|
|
10
|
+
export default function TermsOfUses(p){
|
|
11
|
+
const props = getScreenProps(p);
|
|
12
|
+
return <Screen
|
|
13
|
+
{...props}
|
|
14
|
+
withDrawer = {false}
|
|
15
|
+
appBarProps = {extendObj({},{
|
|
16
|
+
backAction : false,
|
|
17
|
+
title,
|
|
18
|
+
actions : [{
|
|
19
|
+
text : "Accepter",
|
|
20
|
+
icon : "check",
|
|
21
|
+
onPress : ({goBack})=>{
|
|
22
|
+
goBack && goBack();
|
|
23
|
+
}
|
|
24
|
+
}],
|
|
25
|
+
}, props.appBarProps)}
|
|
26
|
+
>
|
|
27
|
+
{React.isComponent(Content)? <Content {...props}/> : React.isValidElement(Content)? Content : null}
|
|
28
|
+
</Screen>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
TermsOfUses.screenName = TERMS_OF_USES;
|
|
33
|
+
|
|
34
|
+
TermsOfUses.authRequired = false;
|
|
35
|
+
|
|
36
|
+
TermsOfUses.Modal = true;
|
|
37
|
+
|
|
38
|
+
TermsOfUses.Link = Link;
|
|
39
|
+
|
|
40
|
+
TermsOfUses.title = title;
|
|
41
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const TERMS_OF_USES = "TERMS_OF_USES";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default "CONTRAT DE LICENCE DU LOGICIEL"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
computerName : "Nom de l'ordinateur",
|
|
3
|
+
operatingSystem : "Système d'exploitation",
|
|
4
|
+
osVersion : "Version",
|
|
5
|
+
model : "Model", //le model du device
|
|
6
|
+
platform : "Plateforme",
|
|
7
|
+
computerUserName : "Utilisateur connecté au système",
|
|
8
|
+
uuid : "Unique id",
|
|
9
|
+
deviceId : "ID du poste de travail",
|
|
10
|
+
id : "Id application", //le bundle id de l'application
|
|
11
|
+
name : "Nom de l'application", //display name of the app
|
|
12
|
+
version : "Version de l'application",
|
|
13
|
+
storageUsage : "Stockage",
|
|
14
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import appConfig from "$capp/config";
|
|
2
|
+
import deviceProps from "./deviceProps";
|
|
3
|
+
import Label from "$ecomponents/Label";
|
|
4
|
+
import theme from "$theme";
|
|
5
|
+
import View from "$ecomponents/View";
|
|
6
|
+
|
|
7
|
+
export default (infos,force)=>{
|
|
8
|
+
infos = defaultObj(infos);
|
|
9
|
+
infos.deviceId = appConfig.deviceId;
|
|
10
|
+
const deviceInfo = [];
|
|
11
|
+
force = force !== undefined ? force : true;
|
|
12
|
+
Object.map(deviceProps,(info,p)=>{
|
|
13
|
+
if(!(p in infos)){
|
|
14
|
+
infos[p] = appConfig.get(p) || undefined;
|
|
15
|
+
}
|
|
16
|
+
if((infos[p])){
|
|
17
|
+
let _info = infos[p];
|
|
18
|
+
if(_info == 'unknown' || !_info) return null;
|
|
19
|
+
const testID = 'RN_DeviceInfo_'+p;
|
|
20
|
+
deviceInfo.push(
|
|
21
|
+
<View testID={testID} textBold key={p} style={[theme.styles.row,theme.styles.w100]}>
|
|
22
|
+
<Label testID = {testID+"_Label"} textBold>{info+" : "}</Label>
|
|
23
|
+
<Label testID = {testID+"_Value"} primary textBold>
|
|
24
|
+
{_info}
|
|
25
|
+
</Label>
|
|
26
|
+
</View>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
return deviceInfo;
|
|
31
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import View from "$ecomponents/View";
|
|
2
|
+
import Label from "$ecomponents/Label";
|
|
3
|
+
import theme from "$theme";
|
|
4
|
+
import appConfig from "$app/config";
|
|
5
|
+
export default function getReleaseLabel(){
|
|
6
|
+
return <View style={[theme.styles.row]}>
|
|
7
|
+
<Label style={[{color:theme.colors.text,fontSize:16}]}>Version </Label>
|
|
8
|
+
<Label style={[{color:theme.colors.primary,fontWeight:'bold',fontSize:18}]}>{appConfig.version} </Label>
|
|
9
|
+
</View>;
|
|
10
|
+
}
|