@fto-consult/expo-ui 1.4.16 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,_path)=>{
16
+ const loopPackages = (packages,projectPath)=>{
19
17
  if(!isObj(packages)) return;
20
- let p = path.resolve(_path,"node_modules");
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
- let package = require(packagePath);
25
- if(!isObj(package) || !package.name) return;
26
- let op = {};
27
- openLibraries[package.name] = op;
28
- if(package.version){
29
- op.version = package.version;
30
- }
31
- if(isValidUrl(package.homepage)){
32
- op.url = package.homepage
33
- } else if(isValidUrl(package.repository)) {
34
- op.url = package.repository;
35
- } else if(isObj(package.repository) && package.repository.url){
36
- op.url = package.repository.url;
37
- }
38
- if(package.license || package.licence){
39
- op.license = typeof package.license =="string"? package.license : typeof package.licence =="string"? package.licence : "";
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 = (_path)=> new Promise((resolve,reject)=>{
46
- let pD = path.resolve(_path,"package.json");
47
- if(fs.existsSync(pD)){
48
- let packages = require(pD);
49
- if(isObj(packages)){
50
- loopPackages(packages.devDependencies,_path);
51
- loopPackages(packages.dependencies,_path);
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
- resolve(openLibraries);
55
- })
56
- const parentPath = require("./parent-package");
57
- Promise.all([
58
- parentPath ? path.resolve(path.dirname(parentPath)): findLicences(dir),
59
- ]).then(()=>{
60
- let s = Object.keys(openLibraries).sort((a,b)=>{
61
- if (a.toLowerCase() < b.toLowerCase()) return -1;
62
- if (a.toLowerCase() > b.toLowerCase()) return 1;
63
- return 0;
64
- });
65
- let content = {};
66
- for(let i in s){
67
- content[s[i]] = openLibraries[s[i]]
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
- content = "export default "+JSON.stringify(content);
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.4.16",
3
+ "version": "1.5.1",
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.14",
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.getDeviceName(),
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
 
@@ -86,7 +86,7 @@ export default function LoginComponent(props){
86
86
  },1000)
87
87
  }
88
88
  },[withPortal])
89
- const {header,children,initialize,contentTop,data:loginData,canGoToNext,keyboardEvents,onSuccess:onLoginSuccess,mutateData,canSubmit:canSubmitForm,onStepChange,...loginProps} = defaultObj(getProps({
89
+ const {header,withScrollView:customWithScrollView,children,initialize,contentTop,data:loginData,canGoToNext,keyboardEvents,onSuccess:onLoginSuccess,mutateData,canSubmit:canSubmitForm,onStepChange,...loginProps} = defaultObj(getProps({
90
90
  ...state,
91
91
  setState,
92
92
  state,
@@ -170,8 +170,9 @@ export default function LoginComponent(props){
170
170
  setState({...state,step:step+1,data})
171
171
  }
172
172
  }
173
-
174
- const wrapperProps = withPortal ? {appBarProps,authRequired:false,title:loginTitle} : { style:styles.wrapper};
173
+ const withScrollView = typeof customWithScrollView =='boolean'? customWithScrollView : true;
174
+ const Wrapper = withPortal ? ScreenWithoutAuthContainer : withScrollView ? ScrollView: View;
175
+ const wrapperProps = withPortal ? {appBarProps,authRequired:false,title:loginTitle,withScrollView} : { style:styles.wrapper};
175
176
  return <Wrapper testID = {testID+"_Wrapper" }{...wrapperProps}>
176
177
  <DialogProvider ref={dialogProviderRef}/>
177
178
  <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 || !isMobileNative() || isPreloader ? 0 : typeof borderRadius =='number'? borderRadius : 7*theme.roundness;
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
- paddingTop : borderRadius,
171
- paddingBottom : borderRadius,
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]}>
@@ -53,7 +53,7 @@ const styles = StyleSheet.create({
53
53
  justifyContent : "center",
54
54
  alignItems : "center",
55
55
  flexDirection : "row",
56
- height,
56
+ maxHeight:height,
57
57
  width,
58
58
  },
59
59
  logoImage : {
@@ -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:PropTypes.object,
171
+ style:StyleProp,
172
172
  appBarProps : PropTypes.object,
173
173
  elevation : PropTypes.number,
174
174
  //appBar : PropTypes.bool,
175
- contentContainerStyle : PropTypes.object,
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,
@@ -14,6 +14,7 @@ import {navigate} from "$cnavigation";
14
14
  import theme from "$theme";
15
15
  import {isMobileNative} from "$cplatform";
16
16
  import appConfig from "$capp/config";
17
+ import Preloader from "$preloader";
17
18
  const UserProfileAvatarComponent = React.forwardRef(({drawerRef,...props},ref)=>{
18
19
  let u = defaultObj(Auth.getLoggedUser());
19
20
  const deviceNameRef = React.useRef(null);
@@ -46,7 +47,10 @@ const UserProfileAvatarComponent = React.forwardRef(({drawerRef,...props},ref)=>
46
47
  label : i18n.lang("logout",'Déconnexion'),
47
48
  icon : "logout",
48
49
  onPress : (a)=>{
49
- closeDrawer(Auth.signOut);
50
+ closeDrawer(()=>{
51
+ Preloader.open("Déconnexion en cours...");
52
+ Auth.signOut().finally(Preloader.close)
53
+ });
50
54
  }
51
55
  }
52
56
  ];
@@ -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 : 'timeline-help',
36
- label : name+", Mises à jour",
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
+ }
@@ -0,0 +1,8 @@
1
+ import TermsOfUses from "./TermsOfUses"
2
+ import PrivacyPolicy from "./PrivacyPolicy";
3
+ import About from "./About";
4
+ export default [
5
+ TermsOfUses,
6
+ PrivacyPolicy,
7
+ About,
8
+ ]
@@ -1,4 +1,6 @@
1
1
  import Auth from "./Auth";
2
+ import Help from "./Help";
2
3
  export default [
3
4
  ...Auth,
5
+ ...Help,
4
6
  ]