@fto-consult/expo-ui 3.6.1 → 4.0.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.
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fto-consult/expo-ui",
3
- "version": "3.6.1",
3
+ "version": "4.0.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
  "@emotion/native": "^11.10.0",
62
62
  "@expo/html-elements": "^0.2.0",
63
63
  "@expo/vector-icons": "^13.0.0",
64
- "@fto-consult/common": "^2.15.4",
64
+ "@fto-consult/common": "^2.17.2",
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.5.2",
@@ -70,7 +70,6 @@
70
70
  "@react-navigation/native-stack": "^6.9.7",
71
71
  "@shopify/flash-list": "1.3.1",
72
72
  "conf": "^10.2.0",
73
- "electron": "^22.1.0",
74
73
  "expo": "^47.0.8",
75
74
  "expo-camera": "~13.1.0",
76
75
  "expo-clipboard": "~4.0.1",
@@ -86,6 +85,7 @@
86
85
  "google-libphonenumber": "^3.2.31",
87
86
  "htmlparser2-without-node-native": "^3.9.2",
88
87
  "mongo-parse": "^2.1.0",
88
+ "node-machine-id": "^1.1.12",
89
89
  "parent-package-json": "^2.0.1",
90
90
  "prop-types": "^15.8.1",
91
91
  "react": "18.1.0",
@@ -109,6 +109,7 @@
109
109
  "sharp-cli": "^2.1.0",
110
110
  "tippy.js": "^6.3.7",
111
111
  "use-event-callback": "^0.1.0",
112
+ "websql": "^2.0.3",
112
113
  "xlsx": "^0.18.5"
113
114
  },
114
115
  "devDependencies": {
@@ -118,6 +119,7 @@
118
119
  "@expo/webpack-config": "^0.17.3",
119
120
  "babel-plugin-inline-dotenv": "^1.7.0",
120
121
  "babel-plugin-module-resolver": "^4.1.0",
121
- "babel-plugin-transform-inline-environment-variables": "^0.4.4"
122
+ "babel-plugin-transform-inline-environment-variables": "^0.4.4",
123
+ "electron": "^22.2.0"
122
124
  }
123
125
  }
package/readMe.md CHANGED
@@ -1,11 +1,20 @@
1
- <!--
2
- Copyright 2022 @fto-consult/Boris Fouomene. All rights reserved.
3
- Use of this source code is governed by a BSD-style
4
- license that can be found in the LICENSE file.
5
- -->
6
-
7
1
  ## Installation des dépendences, packages de dévéloppement
8
2
 
9
- ```
3
+ ```javascript
10
4
  npm i --D @babel/plugin-proposal-export-namespace-from @babel/preset-react babel-plugin-inline-dotenv babel-plugin-module-resolver babel-plugin-transform-inline-environment-variables @expo/metro-config @expo/webpack-config
11
5
  ```
6
+
7
+ ## **#ELECTRON**
8
+
9
+ ## Pré-requis : Installer le package electron en global :  `npm i -g electron`
10
+
11
+ ### **Commandes electron : expo-ui electron cli**
12
+
13
+ ### `expo-ui [build|start] [compile] [build] [url=local-url] [platform=[window|linux|mac]] [arch=x64|x86]`
14
+
15
+ 1. \[build|start\], le script à exécuter : build|start
16
+ 2. \[compile\], si l'application sera compilé, via la commande expo export:web; valide lorsque aucune url n'est spécifiée
17
+ 3. \[build\]\], si l'exécutable sera crée pour la plateforme \[platform\], valide uniquement pour le script \<\<build>>
18
+ 4. \[url=local-url\], l'url à ouvrir via l'application electron (exemple : http://localhost:19006/), valide uniquement pour le script \<\<start>>;
19
+ 5. \[plateforem\], la plateforme vers laquelle on souhaite exporter l'exécutable electron, vailde uniquement pour le script \<\<build>>
20
+ 6. \[arch\], l'architecture de l'exécutable à exporter, valide uniquement pour le script \<\<build>>
@@ -3134,10 +3134,11 @@ export default class CommonDatagridComponent extends AppComponent {
3134
3134
  Elle pourra éventuellement passer directement la limite et les filtres à la fonction fetchdata
3135
3135
  */
3136
3136
  fetchData ({cb,callback,force,fetchOptions,...rest}){
3137
- if(!this._isMounted()) return Promise.resolve(this.state.data);
3137
+ const sData = this.INITIAL_STATE.data || (!this.isTableData() || typeof this.props.fetchData !='function') ? this.props.data : this.state.data;
3138
+ if(!this._isMounted()) return Promise.resolve(sData);
3138
3139
  if(this.isFetchingData) {
3139
3140
  if(!isPromise(this.fetchingPromiseData)){
3140
- this.fetchingPromiseData = Promise.resolve(this.state.data)
3141
+ this.fetchingPromiseData = Promise.resolve(sData)
3141
3142
  }
3142
3143
  return this.fetchingPromiseData;
3143
3144
  };
@@ -3152,15 +3153,15 @@ export default class CommonDatagridComponent extends AppComponent {
3152
3153
  fetchOptions = this.getFetchOptions({fetchOptions,convertToSQL:false});
3153
3154
  if(typeof this.props.fetchOptionsMutator =='function' && this.props.fetchOptionsMutator(fetchOptions) === false){
3154
3155
  this.isFetchingData = false;
3155
- return resolve(this.state.data);
3156
+ return resolve(sData);
3156
3157
  }
3157
- if(this.beforeFetchData(fetchOptions) === false) return resolve(this.state.data);
3158
+ if(this.beforeFetchData(fetchOptions) === false) return resolve(sData);
3158
3159
  if(this.willConvertFiltersToSQL()){
3159
3160
  fetchOptions.selector = convertToSQL(fetchOptions.selector);
3160
3161
  }
3161
3162
  if(typeof this.props.beforeFetchData =='function' && this.props.beforeFetchData({...rest,context:this,force,fetchOptions,options:fetchOptions}) === false){
3162
3163
  this.isFetchingData = false;
3163
- return resolve(this.state.data);
3164
+ return resolve(sData);
3164
3165
  }
3165
3166
  if(force !== true && isArray(this.INITIAL_STATE.data)) {
3166
3167
  return this.resolveFetchedDataPromise({cb,data:this.INITIAL_STATE.data}).then(resolve).catch(reject)
@@ -3190,8 +3191,7 @@ export default class CommonDatagridComponent extends AppComponent {
3190
3191
  });;
3191
3192
  })
3192
3193
  } else {
3193
- let data = !isPromise(fetchData)? Object.toArray(fetchData) : [];
3194
- ///if(data.length <=0) data = this.state.data;
3194
+ const data = isObjOrArray(fetchData)? fetchData : sData;
3195
3195
  return this.resolveFetchedDataPromise({cb,data,force}).then((data)=>{
3196
3196
  resolve(data);
3197
3197
  }).catch((e)=>{
@@ -3457,7 +3457,7 @@ export default class CommonDatagridComponent extends AppComponent {
3457
3457
  this[this.hidePreloaderOnRenderKey] = !!toggle;
3458
3458
  }
3459
3459
  onRender(){
3460
- if(!this.canHidePreloaderOnRender()) return ;
3460
+ if(!this.canHidePreloaderOnRender() && this.isTableData() && this.canFetchOnlyVisibleColumns()) return ;
3461
3461
  if(typeof this.props.onRender ==='function' && this.props.onRender({context:this}) === false){
3462
3462
  return ;
3463
3463
  }
@@ -3545,11 +3545,11 @@ export default class CommonDatagridComponent extends AppComponent {
3545
3545
  }
3546
3546
  }
3547
3547
  getPointerEvents(){
3548
- if(this.enablePointerEventsRef.current) return true;
3549
- if(this.props.isLoading){
3548
+ if(this.enablePointerEventsRef.current) return "auto";
3549
+ if(this.props.isLoading == true){
3550
3550
  return "none";
3551
3551
  }
3552
- return this.isLoading()? "none":"auto";
3552
+ return "auto";
3553
3553
  }
3554
3554
  updateLayout(p){
3555
3555
  this.measureLayout(state=>{
@@ -125,7 +125,6 @@ const DatagridFactory = (Factory)=>{
125
125
  chartContainerProps = defaultObj(chartContainerProps);
126
126
  testID = this.getTestID();
127
127
  rest = defaultObj(rest);
128
- let showDataSourceSelector = false;
129
128
  if(dataSourceSelector === true){
130
129
  showDataSourceSelector = true;
131
130
  } else if(dataSourceSelector ===false){
@@ -59,7 +59,7 @@ const TableComponent = React.forwardRef(({containerProps,sortedColumn,listContai
59
59
  const hasEmptyData = emptyData && React.isValidElement(emptyData);
60
60
  const layoutRef = React.useRef({});
61
61
 
62
- const preparedColumns = React.useStableMemo(()=>{
62
+ const preparedColumns = React.useMemo(()=>{
63
63
  const cols = {},headers = {},footers = {},filters = {},vColumnsMapping = [],visibleColumns = [],columnsNames = [];
64
64
  let hasFooters = false;
65
65
  columnProps = defaultObj(columnProps);
@@ -278,11 +278,7 @@ const TableComponent = React.forwardRef(({containerProps,sortedColumn,listContai
278
278
  style = {[allScrollViewProps.style,headerScrollViewProps.style,{height:'100%',flex:1,flexWrap:'wrap'}]}
279
279
  ref={headerScrollViewRef}
280
280
  horizontal {...allScrollViewProps}
281
- onScroll = {getOnScrollCb([scrollViewRef,footerScrollViewRef],null,(args)=>{
282
- return;
283
- const nativeEvent = args.nativeEvent;
284
- console.log(nativeEvent," is n event");
285
- })}
281
+ onScroll = {getOnScrollCb([scrollViewRef,footerScrollViewRef])}
286
282
  showsHorizontalScrollIndicator
287
283
  >
288
284
  <View testID={testID+"Header2FootersWrapper"} style={[theme.styles.w100]}>
package/src/index.js CHANGED
@@ -7,7 +7,7 @@ import { NavigationContainer} from '@react-navigation/native';
7
7
  import {navigationRef} from "$cnavigation"
8
8
  import NetInfo from '$utils/NetInfo';
9
9
  import Auth from "$cauth";
10
- import {isNativeMobile} from "$cplatform";
10
+ import {isNativeMobile,isElectron} from "$cplatform";
11
11
  import Navigation from "./navigation";
12
12
  import {set as setSession,get as getSession} from "$session";
13
13
  import { showConfirm } from "$ecomponents/Dialog";
@@ -17,9 +17,10 @@ import {notify} from "$ecomponents/Dialog";
17
17
  import {decycle} from "$utils/json";
18
18
  import init from "$capp/init";
19
19
  import { setIsInitialized} from "$capp/utils";
20
- import {isObj,isNonNullString} from "$cutils";
20
+ import {isObj,isNonNullString,isPromise,defaultObj,defaultStr} from "$cutils";
21
21
  import {loadFonts} from "$ecomponents/Icon/Font";
22
22
  import appConfig from "$capp/config";
23
+ import Preloader from "$preloader";
23
24
 
24
25
  let MAX_BACK_COUNT = 1;
25
26
  let countBack = 0;
@@ -71,6 +72,56 @@ function App(props) {
71
72
  });
72
73
  };
73
74
  const subscription = AppState.addEventListener('change', AppStateService.getInstance().handleAppStateChange);
75
+ const beforeExitApp = (cb)=>{
76
+ return new Promise((resolve,reject)=>{
77
+ Preloader.closeAll();
78
+ showConfirm({
79
+ title : "Quitter l'application",
80
+ message : 'Voulez vous vraiment quitter l\'application?',
81
+ yes : 'Oui',
82
+ no : 'Non',
83
+ onSuccess : ()=>{
84
+ const foreceExit = ()=>{
85
+ BackHandler.exitApp();
86
+ if(isElectron() && window.ELECTRON && typeof ELECTRON.exitApp =='function'){
87
+ ELECTRON.exitApp({APP});
88
+ }
89
+ }
90
+ const exit = ()=>{
91
+ if(typeof appConfig.beforeExit =='function'){
92
+ const r2 = appConfig.beforeExit()
93
+ if(!isPromise(r2)){
94
+ throw {message:'La fonction before exit de appConfig.beforeExit doit retourner une promesse',returnedResult:r2}
95
+ }
96
+ return r2.then(foreceExit).catch(reject);
97
+ }
98
+ foreceExit();
99
+ }
100
+ const r = {APP,exit};
101
+ APP.trigger(APP.EVENTS.BEFORE_EXIT,exit,(result)=>{
102
+ if(isObj(result) || Array.isArray(result)){
103
+ for(let ik in result){
104
+ if(result[ik] === false) return reject({message:'EXIT APP DENIED BY BEFORE EXIT EVENT HANDLER AT POSITON {0}'.sprintf(ik)});
105
+ }
106
+ }
107
+ resolve(r);
108
+ if(typeof cb =='function'){
109
+ cb(r);
110
+ }
111
+ });
112
+ },
113
+ onCancel : reject
114
+ })
115
+ })
116
+ }
117
+ /**** onBeforeExit prend en paramètre la fonction de rappel CB, qui lorsque la demande de sortie d'application est acceptée, alors elle est exécutée */
118
+ if(typeof APP.beforeExit !=='function'){
119
+ Object.defineProperties(APP,{
120
+ beforeExit : {
121
+ value : beforeExitApp,
122
+ }
123
+ })
124
+ }
74
125
  const backAction = (args) => {
75
126
  if(navigationRef && navigationRef.canGoBack()? true : false){
76
127
  resetExitCounter();
@@ -92,21 +143,10 @@ function App(props) {
92
143
  return false;
93
144
  }
94
145
  isBackConfirmShowing = true;
95
- showConfirm({
96
- title : "Quitter l'application",
97
- message : 'Voulez vous vraiment quitter l\'application?',
98
- yes : 'Oui',
99
- no : 'Non',
100
- onSuccess : ()=>{
101
- isBackConfirmShowing = false;
102
- countBack = 0;
103
- BackHandler.exitApp();
104
- },
105
- onCancel : ()=>{
106
- isBackConfirmShowing = false;
107
- countBack = 0;
108
- return;
109
- }
146
+ return beforeExitApp().finally(x=>{
147
+ isBackConfirmShowing = false;
148
+ }).then(({exit})=>{
149
+ exit();
110
150
  })
111
151
  };
112
152
  const unsubscribeNetInfo = NetInfo.addEventListener(state => {
@@ -136,7 +176,11 @@ function App(props) {
136
176
  events.push(navigationRef.addListener(i,Events[i]));
137
177
  }
138
178
  }
139
-
179
+ APP.onElectron("BEFORE_EXIT",()=>{
180
+ return beforeExitApp().then(({exit})=>{
181
+ exit();
182
+ })
183
+ });
140
184
  APP.on(APP.EVENTS.BACK_BUTTON,backAction);
141
185
  return () => {
142
186
  APP.off(APP.EVENTS.BACK_BUTTON,backAction);