@fto-consult/expo-ui 7.17.9 → 7.18.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.
package/package.json CHANGED
@@ -1,139 +1,140 @@
1
- {
2
- "name": "@fto-consult/expo-ui",
3
- "version": "7.17.9",
4
- "description": "Bibliothèque de composants UI Expo,react-native",
5
- "scripts": {
6
- "clear-npx-cache": "npx clear-npx-cache",
7
- "publish1": "npm publish --access=public",
8
- "unpublish": "npm -f unpublish @fto-consult/expo-ui",
9
- "build-web": "",
10
- "start": "npx expo start --dev --no-minify",
11
- "start-d": "npx expo start -c --no-dev --no-minify",
12
- "start-p": "npm run start-d",
13
- "expo-start-client": "npx expo start --dev --no-minify --dev-client",
14
- "start-m": "npx expo start - c--dev--no -minify",
15
- "android": "npx expo start --android -c",
16
- "ios": "npx expo start --ios",
17
- "web": "npx expo start --web",
18
- "web-c": "npx expo start --web -c",
19
- "eject": "expo eject",
20
- "emulator": "npm run android-emulator",
21
- "web-server": "npx serve web-build",
22
- "build-android": "eas build --clear-cache -p android --profile preview",
23
- "build-android-local": "eas build --platform android --local",
24
- "build-android-dist": "eas build --clear-cache -p android",
25
- "build-ios": "eas build --clear-cache -p ios --profile preview",
26
- "build-ios-dist": "eas build --clear-cache -p ios",
27
- "install-apk": "adb -s emulator-5554 install myapp.apk",
28
- "android-emulator": "emulator -avd EMULATOR",
29
- "flipper": "npx cross-env METRO_SERVER_PORT=19000 E:\\Studies\\react-native\\debugger\\Flipper-win\\Flipper.exe",
30
- "test:build": "electron-webpack && electron-builder --dir -c.compression=store -c.mac.identity=null",
31
- "compile-electron": "webpack --env platform=electron",
32
- "compile-electron-p": "webpack --config ./electron/webpack.config.js --mode=production",
33
- "electron": "electron ./electron",
34
- "logcat": "adb -d logcat com.ftc.apps.salite1:E > errors.txt",
35
- "logcat-export": "adb -d logcat com.ftc.apps.salite1 *:S > logcat.txt",
36
- "electron-c": "npm run compile-electron && npm run electron",
37
- "electron-p": "npm run compile-electron-p && npm run electron",
38
- "update-app-version": "node ./update-app-version.js",
39
- "find-licenses": "node ./find-licenses.js",
40
- "fix-dependencies": "expo-cli doctor --fix-dependencies",
41
- "expo-fix": "npx expo install --fix",
42
- "update-apexchart": "node ./bin/update-appex-chart.js",
43
- "update-pdfmake": "node ./bin/update-pdfmake.js",
44
- "test-bin": "node ./bin/index.js",
45
- "update-appexchart": "npm run update-apexchart",
46
- "delete-node-modules": "rimraf ./**/node_modules",
47
- "dev": "npx expo start --no-dev --minify -c",
48
- "modifier-url-remote-git": "git remote set-url origin 'https://borispipo@github.com/borispipo/smart-eneo.git'",
49
- "update": "npm i @fto-consult/electron-gen@latest pdfmake@latest expo @emotion/native@latest react-native-big-list@latest apexcharts@latest file-saver@latest fs-extra@latest google-libphonenumber@latest @pchmn/expo-material3-theme@latest @emotion/native@latest @fto-consult/common@latest @react-navigation/stack react-native-blob-util react-native-iphone-x-helper@latest react-native-mime-types@latest react-native-paper@5 react-native-paper-dates@latest @react-navigation/native@latest @react-navigation/native-stack@latest react-virtuoso@latest tippy.js@latest websql@latest xlsx@latest react-native-web@latest react-dom@latest && npx expo install --fix && npm run update-apexchart && npm run update-pdfmake && npm run find-licenses"
50
- },
51
- "bin": {
52
- "expo-ui": "./bin/index.js"
53
- },
54
- "repository": {
55
- "type": "git",
56
- "url": "git+https://github.com/borispipo/expo-ui.git"
57
- },
58
- "keywords": [
59
- "Expo",
60
- "React-Native"
61
- ],
62
- "author": "Boris Fouomene",
63
- "license": "ISC",
64
- "bugs": {
65
- "url": "https://github.com/borispipo/expo-ui/issues"
66
- },
67
- "homepage": "https://github.com/borispipo/expo-ui#readme",
68
- "dependencies": {
69
- "@emotion/native": "^11.11.0",
70
- "@emotion/react": "^11.11.1",
71
- "@expo/html-elements": "^0.5.1",
72
- "@expo/vector-icons": "^13.0.0",
73
- "@faker-js/faker": "^8.0.2",
74
- "@fto-consult/common": "^4.2.1",
75
- "@fto-consult/electron-gen": "^2.2.1",
76
- "@pchmn/expo-material3-theme": "^1.3.1",
77
- "@react-native-async-storage/async-storage": "1.18.2",
78
- "@react-native-community/datetimepicker": "7.2.0",
79
- "@react-native-community/netinfo": "9.3.10",
80
- "@react-native/assets-registry": "^0.72.0",
81
- "@react-navigation/native": "^6.1.9",
82
- "@react-navigation/native-stack": "^6.9.17",
83
- "@react-navigation/stack": "^6.3.20",
84
- "@shopify/flash-list": "1.4.3",
85
- "apexcharts": "^3.45.1",
86
- "commander": "^11.1.0",
87
- "expo": "^49.0.21",
88
- "expo-camera": "~13.4.4",
89
- "expo-clipboard": "~4.3.1",
90
- "expo-font": "~11.4.0",
91
- "expo-image-picker": "~14.3.2",
92
- "expo-linking": "~5.0.2",
93
- "expo-sharing": "~11.5.0",
94
- "expo-sqlite": "~11.3.3",
95
- "expo-status-bar": "~1.6.0",
96
- "expo-system-ui": "~2.4.0",
97
- "expo-web-browser": "~12.3.2",
98
- "file-saver": "^2.0.5",
99
- "fs-extra": "^11.2.0",
100
- "google-libphonenumber": "^3.2.33",
101
- "htmlparser2-without-node-native": "^3.9.2",
102
- "is-plain-obj": "^4.1.0",
103
- "js-base64": "^3.7.5",
104
- "pdfmake": "^0.2.9",
105
- "process": "^0.11.10",
106
- "prop-types": "^15.8.1",
107
- "react": "^18.2.0",
108
- "react-content-loader": "^6.2.1",
109
- "react-dom": "^18.2.0",
110
- "react-native": "0.72.6",
111
- "react-native-big-list": "^1.6.1",
112
- "react-native-blob-util": "^0.18.6",
113
- "react-native-get-random-values": "~1.9.0",
114
- "react-native-iphone-x-helper": "^1.3.1",
115
- "react-native-mime-types": "^2.4.0",
116
- "react-native-paper": "^5.11.6",
117
- "react-native-paper-dates": "^0.21.7",
118
- "react-native-reanimated": "~3.3.0",
119
- "react-native-safe-area-context": "4.6.3",
120
- "react-native-screens": "~3.22.0",
121
- "react-native-svg": "13.9.0",
122
- "react-native-web": "^0.19.10",
123
- "react-native-webview": "13.2.2",
124
- "react-virtuoso": "^4.6.2",
125
- "sanitize-filename": "^1.6.3",
126
- "sharp-cli": "^2.1.0",
127
- "tippy.js": "^6.3.7",
128
- "uninstall": "^0.0.0",
129
- "websql": "^2.0.3",
130
- "xlsx": "^0.18.5"
131
- },
132
- "devDependencies": {
133
- "@babel/plugin-proposal-export-namespace-from": "^7.18.9",
134
- "@expo/metro-config": "^0.10.7",
135
- "@expo/webpack-config": "^19.0.0",
136
- "babel-plugin-inline-dotenv": "^1.7.0",
137
- "babel-plugin-module-resolver": "^5.0.0"
138
- }
139
- }
1
+ {
2
+ "name": "@fto-consult/expo-ui",
3
+ "version": "7.18.1",
4
+ "description": "Bibliothèque de composants UI Expo,react-native",
5
+ "scripts": {
6
+ "clear-npx-cache": "npx clear-npx-cache",
7
+ "publish1": "npm publish --access=public",
8
+ "unpublish": "npm -f unpublish @fto-consult/expo-ui",
9
+ "build-web": "",
10
+ "start": "npx expo start --dev --no-minify",
11
+ "start-d": "npx expo start -c --no-dev --no-minify",
12
+ "start-p": "npm run start-d",
13
+ "expo-start-client": "npx expo start --dev --no-minify --dev-client",
14
+ "start-m": "npx expo start - c--dev--no -minify",
15
+ "android": "npx expo start --android -c",
16
+ "ios": "npx expo start --ios",
17
+ "web": "npx expo start --web",
18
+ "web-c": "npx expo start --web -c",
19
+ "eject": "expo eject",
20
+ "emulator": "npm run android-emulator",
21
+ "web-server": "npx serve web-build",
22
+ "build-android": "eas build --clear-cache -p android --profile preview",
23
+ "build-android-local": "eas build --platform android --local",
24
+ "build-android-dist": "eas build --clear-cache -p android",
25
+ "build-ios": "eas build --clear-cache -p ios --profile preview",
26
+ "build-ios-dist": "eas build --clear-cache -p ios",
27
+ "install-apk": "adb -s emulator-5554 install myapp.apk",
28
+ "android-emulator": "emulator -avd EMULATOR",
29
+ "flipper": "npx cross-env METRO_SERVER_PORT=19000 E:\\Studies\\react-native\\debugger\\Flipper-win\\Flipper.exe",
30
+ "test:build": "electron-webpack && electron-builder --dir -c.compression=store -c.mac.identity=null",
31
+ "compile-electron": "webpack --env platform=electron",
32
+ "compile-electron-p": "webpack --config ./electron/webpack.config.js --mode=production",
33
+ "electron": "electron ./electron",
34
+ "logcat": "adb -d logcat com.ftc.apps.salite1:E > errors.txt",
35
+ "logcat-export": "adb -d logcat com.ftc.apps.salite1 *:S > logcat.txt",
36
+ "electron-c": "npm run compile-electron && npm run electron",
37
+ "electron-p": "npm run compile-electron-p && npm run electron",
38
+ "update-app-version": "node ./update-app-version.js",
39
+ "find-licenses": "node ./find-licenses.js",
40
+ "fix-dependencies": "expo-cli doctor --fix-dependencies",
41
+ "expo-fix": "npx expo install --fix",
42
+ "update-apexchart": "node ./bin/update-appex-chart.js",
43
+ "update-pdfmake": "node ./bin/update-pdfmake.js",
44
+ "test-bin": "node ./bin/index.js",
45
+ "update-appexchart": "npm run update-apexchart",
46
+ "delete-node-modules": "rimraf ./**/node_modules",
47
+ "dev": "npx expo start --no-dev --minify -c",
48
+ "modifier-url-remote-git": "git remote set-url origin 'https://borispipo@github.com/borispipo/smart-eneo.git'",
49
+ "update": "npm i @fto-consult/electron-gen@latest pdfmake@latest expo @emotion/native@latest react-native-big-list@latest apexcharts@latest file-saver@latest fs-extra@latest google-libphonenumber@latest @pchmn/expo-material3-theme@latest @emotion/native@latest @fto-consult/common@latest @react-navigation/stack react-native-blob-util react-native-iphone-x-helper@latest react-native-mime-types@latest react-native-paper@5 react-native-paper-dates@latest @react-navigation/native@latest @react-navigation/native-stack@latest react-virtuoso@latest tippy.js@latest websql@latest xlsx@latest react-native-web@latest react-dom@latest && npx expo install --fix && npm run update-apexchart && npm run update-pdfmake && npm run find-licenses"
50
+ },
51
+ "bin": {
52
+ "expo-ui": "./bin/index.js"
53
+ },
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "git+https://github.com/borispipo/expo-ui.git"
57
+ },
58
+ "keywords": [
59
+ "Expo",
60
+ "React-Native"
61
+ ],
62
+ "author": "Boris Fouomene",
63
+ "license": "ISC",
64
+ "bugs": {
65
+ "url": "https://github.com/borispipo/expo-ui/issues"
66
+ },
67
+ "homepage": "https://github.com/borispipo/expo-ui#readme",
68
+ "dependencies": {
69
+ "@emotion/native": "^11.11.0",
70
+ "@emotion/react": "^11.11.1",
71
+ "@expo/html-elements": "^0.5.1",
72
+ "@expo/vector-icons": "^13.0.0",
73
+ "@faker-js/faker": "^8.0.2",
74
+ "@fto-consult/common": "^4.4.0",
75
+ "@fto-consult/electron-gen": "^2.2.1",
76
+ "@fto-consult/expo-ui": "^7.17.9",
77
+ "@pchmn/expo-material3-theme": "^1.3.1",
78
+ "@react-native-async-storage/async-storage": "1.18.2",
79
+ "@react-native-community/datetimepicker": "7.2.0",
80
+ "@react-native-community/netinfo": "9.3.10",
81
+ "@react-native/assets-registry": "^0.72.0",
82
+ "@react-navigation/native": "^6.1.9",
83
+ "@react-navigation/native-stack": "^6.9.17",
84
+ "@react-navigation/stack": "^6.3.20",
85
+ "@shopify/flash-list": "1.4.3",
86
+ "apexcharts": "^3.45.1",
87
+ "commander": "^11.1.0",
88
+ "expo": "^49.0.21",
89
+ "expo-camera": "~13.4.4",
90
+ "expo-clipboard": "~4.3.1",
91
+ "expo-font": "~11.4.0",
92
+ "expo-image-picker": "~14.3.2",
93
+ "expo-linking": "~5.0.2",
94
+ "expo-sharing": "~11.5.0",
95
+ "expo-sqlite": "~11.3.3",
96
+ "expo-status-bar": "~1.6.0",
97
+ "expo-system-ui": "~2.4.0",
98
+ "expo-web-browser": "~12.3.2",
99
+ "file-saver": "^2.0.5",
100
+ "fs-extra": "^11.2.0",
101
+ "google-libphonenumber": "^3.2.33",
102
+ "htmlparser2-without-node-native": "^3.9.2",
103
+ "is-plain-obj": "^4.1.0",
104
+ "js-base64": "^3.7.5",
105
+ "pdfmake": "^0.2.9",
106
+ "process": "^0.11.10",
107
+ "prop-types": "^15.8.1",
108
+ "react": "^18.2.0",
109
+ "react-content-loader": "^6.2.1",
110
+ "react-dom": "^18.2.0",
111
+ "react-native": "0.72.6",
112
+ "react-native-big-list": "^1.6.1",
113
+ "react-native-blob-util": "^0.18.6",
114
+ "react-native-get-random-values": "~1.9.0",
115
+ "react-native-iphone-x-helper": "^1.3.1",
116
+ "react-native-mime-types": "^2.4.0",
117
+ "react-native-paper": "^5.11.7",
118
+ "react-native-paper-dates": "^0.21.7",
119
+ "react-native-reanimated": "~3.3.0",
120
+ "react-native-safe-area-context": "4.6.3",
121
+ "react-native-screens": "~3.22.0",
122
+ "react-native-svg": "13.9.0",
123
+ "react-native-web": "^0.19.10",
124
+ "react-native-webview": "13.2.2",
125
+ "react-virtuoso": "^4.6.2",
126
+ "sanitize-filename": "^1.6.3",
127
+ "sharp-cli": "^2.1.0",
128
+ "tippy.js": "^6.3.7",
129
+ "uninstall": "^0.0.0",
130
+ "websql": "^2.0.3",
131
+ "xlsx": "^0.18.5"
132
+ },
133
+ "devDependencies": {
134
+ "@babel/plugin-proposal-export-namespace-from": "^7.18.9",
135
+ "@expo/metro-config": "^0.10.7",
136
+ "@expo/webpack-config": "^19.0.0",
137
+ "babel-plugin-inline-dotenv": "^1.7.0",
138
+ "babel-plugin-module-resolver": "^5.0.0"
139
+ }
140
+ }
@@ -20,13 +20,11 @@ import Label from "$ecomponents/Label";
20
20
  import { StyleSheet} from "react-native";
21
21
  import View from "$ecomponents/View";
22
22
  import theme from "$theme";
23
- import useSWR from "$swr";
24
23
  import {getRowsPerPagesLimits} from "./Common/utils";
25
24
  import PropTypes from "prop-types";
26
25
  import {Menu} from "$ecomponents/BottomSheet";
27
26
  import session from "$session";
28
- import { SWR_REFRESH_TIMEOUT } from "$econtext/utils";
29
- import useContext,{useScreen} from "$econtext/hooks";
27
+ import {useScreen,useSWR} from "$econtext/hooks";
30
28
 
31
29
  export const getSessionKey = ()=>{
32
30
  return Auth.getSessionKey("swrDatagrid");
@@ -46,25 +44,6 @@ export const setSessionData = (key,value)=>{
46
44
  }
47
45
 
48
46
 
49
- /***@see : https://swr.vercel.app/docs/api */
50
-
51
- export const getSWROptions = (defTimeout)=>{
52
- const delay = defaultNumber(defTimeout,SWR_REFRESH_TIMEOUT);
53
- return {
54
- dedupingInterval : delay,
55
- errorRetryInterval : Math.max(delay*2,SWR_REFRESH_TIMEOUT),
56
- errorRetryCount : 5,
57
- revalidateOnMount : false,//enable or disable automatic revalidation when component is mounted
58
- revalidateOnFocus : true, //automatically revalidate when window gets focused (details)
59
- revalidateOnReconnect : true, //automatically revalidate when the browser regains a network
60
- refreshInterval : delay, //5 minutes : Disabled by default: refreshInterval = 0, If set to a number, polling interval in milliseconds, If set to a function, the function will receive the latest data and should return the interval in milliseconds
61
- refreshWhenHidden : false, //polling when the window is invisible (if refreshInterval is enabled)
62
- refreshWhenOffline : false, //polling when the browser is offline (determined by navigator.onLine)
63
- shouldRetryOnError : false, //retry when fetcher has an error
64
- dedupingInterval : delay,//dedupe requests with the same key in this time span in milliseconds
65
- }
66
- }
67
-
68
47
  const isValidMakePhoneCallProps = p=> isObj(p) && Object.size(p,true) || typeof p ==='function';
69
48
  /****la fonction fetcher doit toujours retourner :
70
49
  * 1. la liste des éléments fetchés dans la props data
@@ -101,9 +80,9 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
101
80
  defaultSortOrder,
102
81
  isLoading : customIsLoading,
103
82
  icon : cIcon,
83
+ swrOptions,
104
84
  ...rest
105
85
  } = props;
106
- const {swrConfig} = useContext();
107
86
  const screenContext = useScreen();
108
87
  rest = defaultObj(rest);
109
88
  rest.exportTableProps = defaultObj(rest.exportTableProps)
@@ -153,6 +132,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
153
132
  title : React.getTextContent(title),
154
133
  },rest.exportTableProps.pdf);
155
134
  const fetchOptionsRef = React.useRef({});
135
+ const isFetchPathNull = fetchPath === null || fetchPath ===false;
156
136
  const fPathRef = React.useRef(defaultStr(fetchPathKey,uniqid("fetchPath")));
157
137
  fetchPath = defaultStr(fetchPath,table?.queryPath,tableName.toLowerCase()).trim();
158
138
  if(fetchPath){
@@ -168,8 +148,10 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
168
148
  const limitRef = React.useRef(!canHandleLimit ?0 : defaultNumber(getSessionData("limit"),500));
169
149
  const isInitializedRef = React.useRef(false);
170
150
  const hasFetchedRef = React.useRef(false);
151
+ swrOptions = defaultObj(swrOptions);
152
+ swrOptions.revalidateOnMount = typeof swrOptions.revalidateOnMount =="boolean"? swrOptions.revalidateOnMount : false;
171
153
  testID = defaultStr(testID,"RNSWRDatagridComponent");
172
- const {error, isValidating,isLoading,data:result,refresh} = useSWR(fetchPath,{
154
+ const {error, isValidating,isLoading,data:result,refresh} = useSWR(isFetchPathNull?null:fetchPath,{
173
155
  fetcher : (url,opts)=>{
174
156
  if(!isInitializedRef.current) {
175
157
  return Promise.resolve({data:[],total:0});
@@ -204,7 +186,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
204
186
  }
205
187
  return apiFetch(url,opts).then(end);
206
188
  },
207
- swrOptions : getSWROptions(swrConfig.refreshTimeout)
189
+ swrOptions,
208
190
  });
209
191
  const dataRef = React.useRef(null);
210
192
  const totalRef = React.useRef(0);
@@ -455,10 +437,11 @@ SWRDatagridComponent.displayName = "SWRDatagridComponent";
455
437
 
456
438
  SWRDatagridComponent.propTypes = {
457
439
  ...Datagrid.propTypes,
440
+ swrOptions : PropTypes.object,//les ooptions supplémentaires à passer à la fonction swr
458
441
  handlePagination : PropTypes.bool, //spécifie si le datagrid prendra en compte la pagination
459
442
  /*** le nom de la colonne de trie par défaut */
460
443
  defaultSortColumn : PropTypes.string,
461
- fetchPath : PropTypes.string,
444
+ fetchPath : PropTypes.oneOfType([PropTypes.string,PropTypes.bool,PropTypes.object]),
462
445
  fetchPathKey : PropTypes.string,//la clé permettant de suffixer l'url fecherPath afin que ce ne soit pas unique pour certaines tables
463
446
  fetchData : PropTypes.func,
464
447
  table : PropTypes.shape({
@@ -3,7 +3,7 @@
3
3
  // license that can be found in the LICENSE file.
4
4
 
5
5
  import Dropdown from "$ecomponents/Dropdown";
6
- import {defaultStr,extendObj,isFunction,defaultVal,isObjOrArray,defaultObj} from "$cutils";
6
+ import {defaultStr,extendObj,isFunction,setQueryParams,defaultVal,isObjOrArray,defaultObj} from "$cutils";
7
7
  import PropTypes from "prop-types";
8
8
  import actions from "$cactions";
9
9
  import {navigateToTableData} from "$enavigation/utils";
@@ -12,6 +12,8 @@ import fetch from "$capi"
12
12
  import React from "$react";
13
13
  import useApp from "$econtext/hooks";
14
14
  import DateLib from "$lib/date";
15
+ import {useSWR} from "$econtext/hooks";
16
+ import stableHash from "stable-hash";
15
17
 
16
18
  /*** la tabledataSelectField permet de faire des requêtes distantes pour rechercher les données
17
19
  * Elle doit prendre en paramètre et de manière requis : les props suivante :
@@ -19,7 +21,7 @@ import DateLib from "$lib/date";
19
21
  * foreignKeyTable : la tableData dans laquelle effectuer les donées de la requêtes
20
22
  * foreignKeyLabel : Le libélé dans la table étrangère
21
23
  */
22
- const TableDataSelectField = React.forwardRef(({foreignKeyColumn,foreignKeyLabelRenderers,onChange,isStructData,getForeignKeyTable:cGetForeignKeyTable,prepareFilters:cPrepareFilters,bindUpsert2RemoveEvents,onAdd,showAdd:customShowAdd,canShowAdd,foreignKeyTable,fetchItemsPath,foreignKeyLabel,foreignKeyLabelIndex,dropdownActions,fields,fetchItems:customFetchItem,parseMangoQueries,mutateFetchedItems,onFetchItems,isFilter,isUpdate,isDocEditing,items,onAddProps,fetchOptions,...props},ref)=>{
24
+ const TableDataSelectField = React.forwardRef(({foreignKeyColumn,swrOptions,foreignKeyLabelRenderers,onChange,isStructData,getForeignKeyTable:cGetForeignKeyTable,prepareFilters:cPrepareFilters,bindUpsert2RemoveEvents,onAdd,showAdd:customShowAdd,canShowAdd,foreignKeyTable,fetchItemsPath,foreignKeyLabel,foreignKeyLabelIndex,dropdownActions,fields,fetchItems:customFetchItem,parseMangoQueries,mutateFetchedItems,onFetchItems,isFilter,isUpdate,isDocEditing,items:customItems,onAddProps,fetchOptions,...props},ref)=>{
23
25
  props.data = defaultObj(props.data);
24
26
  const type = defaultStr(props.type)?.toLowerCase();
25
27
  isStructData = isStructData || type?.replaceAll("-","").replaceAll("_","").trim().contains("structdata");
@@ -38,16 +40,17 @@ const TableDataSelectField = React.forwardRef(({foreignKeyColumn,foreignKeyLabel
38
40
  }
39
41
  const getForeignKeyTable = typeof cGetForeignKeyTable =='function'? cGetForeignKeyTable : isStructData ? getStructData: appGetForeignKeyTable;
40
42
  parseMangoQueries = defaultBool(parseMangoQueries,datagrid?.parseMangoQueries);
43
+ const parseMangoQueriesRef = React.useRef(parseMangoQueries);
44
+ parseMangoQueriesRef.current = parseMangoQueries;
41
45
  const foreignKeyTableStr = defaultStr(foreignKeyTable,props.tableName,props.table);
46
+ const errors = [];
42
47
  if(typeof getForeignKeyTable !=='function'){
43
- console.error("la fonction getTableData non définie des les paramètres d'initialisation de l'application!!! Rassurez vous d'avoir définier cette fonction!!, options : foreignKeyTable:",foreignKeyTable,"foreignKeyColumn:",foreignKeyColumn,props)
44
- return null;
48
+ errors.push("la fonction getTableData non définie des les paramètres d'initialisation de l'application!!! Rassurez vous d'avoir définier cette fonction!!, options : foreignKeyTable:",foreignKeyTable,"foreignKeyColumn:",foreignKeyColumn,props)
45
49
  }
46
50
  let fKeyTable = getForeignKeyTable(foreignKeyTableStr,props);
47
51
  fetchItemsPath = defaultStr(fetchItemsPath).trim();
48
52
  if(!fetchItemsPath && (!isObj(fKeyTable) || !(defaultStr(fKeyTable.tableName,fKeyTable.table)))){
49
- console.error("type de données invalide pour la foreignKeyTable ",foreignKeyTable," label : ",foreignKeyLabel,fKeyTable," composant SelectTableData",foreignKeyColumn,foreignKeyTable,props);
50
- return null;
53
+ errors.push("type de données invalide pour la foreignKeyTable ",foreignKeyTable," label : ",foreignKeyLabel,fKeyTable," composant SelectTableData",foreignKeyColumn,foreignKeyTable,props);
51
54
  }
52
55
  fKeyTable = defaultObj(fKeyTable);
53
56
  foreignKeyTable = defaultStr(fKeyTable.tableName,fKeyTable.table,foreignKeyTable).trim().toUpperCase();
@@ -61,16 +64,7 @@ const TableDataSelectField = React.forwardRef(({foreignKeyColumn,foreignKeyLabel
61
64
  }
62
65
  }
63
66
  const isMounted = React.useIsMounted();
64
-
65
- const [stateItems,setItems] = React.useState([]);
66
- const [isLoading,setIsLoading] = React.useState(true);
67
- fetchOptions = Object.clone(defaultObj(fetchOptions));
68
- const queryPath = fetchItemsPath || typeof fKeyTable.queryPath =='string' && fKeyTable.queryPath || typeof fKeyTable.fetchPath =='string' && fKeyTable.fetchPath || '';
69
-
70
- isUpdate = defaultBool(isUpdate,typeof isDocEditing ==='function' && isDocEditing({data:props.data,foreignKeyTable,foreignKeyColumn}));
71
- if(isFilter){
72
- isUpdate = false;
73
- }
67
+ const queryPath = fetchItemsPath || typeof fKeyTable.queryPath =='string' && fKeyTable.queryPath || foreignKeyTable;
74
68
  const defaultFields = Array.isArray(foreignKeyColumn)? foreignKeyColumn : [foreignKeyColumn];
75
69
  if(Array.isArray(foreignKeyLabel)){
76
70
  foreignKeyLabel.map(f=>{
@@ -83,42 +77,102 @@ const TableDataSelectField = React.forwardRef(({foreignKeyColumn,foreignKeyLabel
83
77
  foreignKeyLabel = foreignKeyLabel.trim();
84
78
  defaultFields.push(foreignKeyLabel);
85
79
  }
86
- if(fetchOptions.fields !== 'all' && (!Array.isArray(fetchOptions.fields) || !fetchOptions.fields.length)){
87
- fetchOptions.fields = defaultFields;
88
- }
89
- if(fetchOptions.fields =='all'){
90
- delete fetchOptions.fields;
91
- }
92
80
  const foreignKeyColumnValue = props.defaultValue;
93
81
  const defaultValueRef = React.useRef(props.multiple ? Object.toArray(foreignKeyColumnValue) : foreignKeyColumnValue);
94
82
  let isDisabled = defaultBool(props.disabled,props.readOnly,false);
95
83
  if(!isDisabled && props.readOnly === true){
96
84
  isDisabled = true;
97
85
  }
98
- if(isUpdate && isNonNullString(foreignKeyColumnValue) && (isDisabled)){
99
- fetchOptions.selector = defaultObj(fetchOptions.selector);
100
- fetchOptions.selector.$and = defaultArray(fetchOptions.selector.$and);
101
- let hasF = false;
102
- for(let i in fetchOptions.selector.$and){
103
- const cFilter = fetchOptions.selector.$and[i];
104
- if(isObj(cFilter)) {
105
- if(cFilter[foreignKeyColumn] === foreignKeyColumnValue){
106
- hasF = true;
107
- break;
108
- }
109
- }
86
+ const hasErrors = !!errors.length;
87
+ if(!hasErrors){
88
+ fetchOptions = Object.clone(defaultObj(fetchOptions));
89
+ if(fetchOptions.fields !== 'all' && (!Array.isArray(fetchOptions.fields) || !fetchOptions.fields.length)){
90
+ fetchOptions.fields = defaultFields;
110
91
  }
111
- if(!hasF){
112
- fetchOptions.selector.$and.push({[foreignKeyColumn] : foreignKeyColumnValue})
92
+ if(fetchOptions.fields =='all'){
93
+ delete fetchOptions.fields;
113
94
  }
114
95
  }
96
+ const hashKey = React.useMemo(()=>{
97
+ return stableHash(fetchOptions);
98
+ },[fetchOptions]);
115
99
  const hasRefreshedRef = React.useRef(false);
100
+ const showAdd = React.useMemo(()=>{
101
+ if(isFilter || !foreignKeyTable) return false;
102
+ if(typeof canShowAdd ==='function'){
103
+ return !!canShowAdd({...props,table:foreignKeyTable,foreignKeyColumn,foreignKeyLabel,sortDir,foreignKeyTableObj:fKeyTable,foreignKeyTable})
104
+ } else if(Auth[isStructData?"isStructDataAllowed":"isTableDataAllowed"]({table:foreignKeyTable,action:'create'})){
105
+ return !!defaultVal(customShowAdd,true);
106
+ }
107
+ return false;
108
+ },[isFilter,foreignKeyTable,customShowAdd]);
109
+
110
+ const fetchItemsRef = React.useRef(customFetchItem);
111
+ fetchItemsRef.current = customFetchItem;
112
+ swrOptions = Object.assign({},swrOptions);
113
+ if(isFilter){
114
+ swrOptions.refreshInterval = 0;
115
+ }
116
+ const restOptionsRef = React.useRef({});
117
+ const fetchedResultRef = React.useRef({});
118
+ restOptionsRef.current = {foreignKeyTable,foreignKeyColumn,foreignKeyLabel,foreignKeyColumnValue,sort,sortColumn,sortDir,foreignKeyTableObj:fKeyTable};
119
+ const queryPathKey = isNonNullString(queryPath) ? setQueryParams(queryPath,{isstabledata:1,"stabledathkey":hashKey,foreignKeyColumn:defaultStr(foreignKeyColumn).toLowerCase()}) : null;
120
+ const onFetchItemsRef = React.useRef();
121
+ onFetchItemsRef.current = onFetchItems;
122
+ const mutateFetchedItemsRef = React.useRef();
123
+ mutateFetchedItemsRef.current = mutateFetchedItems;
124
+ const {isLoading:cIsLoading,data:fetchedItems,isValidating,refresh} = useSWR(hasErrors?null:queryPathKey,{
125
+ fetcher : (url,opts1)=>{
126
+ if(typeof beforeFetchItems ==='function' && beforeFetchItems({fetchOptions}) === false) return Promise.resolve(fetchedResultRef.current);
127
+ let opts = Object.clone(fetchOptions);
128
+ if(parseMangoQueries.current){
129
+ opts.selector = filtersParseMangoQueries(opts.selector);
130
+ opts = getFetchOptions(opts);
131
+ delete opts.selector;
132
+ } else {
133
+ opts = {fetchOptions:opts};
134
+ }
135
+ opts.showError = false;
136
+ const cFetch = typeof fetchItemsRef.current =="function" && fetchItemsRef.current || false;
137
+ const fetchingOpts = {...props,...opts1,...opts,...restOptionsRef.current};
138
+ return Promise.resolve((cFetch||fetch)(queryPath||url,fetchingOpts)).then((args)=>{
139
+ if(Array.isArray(args)){
140
+ args = {items : args};
141
+ } else if(!isObj(args)) {
142
+ args = {items:[]}
143
+ }
144
+ args.items = args.data = Array.isArray(args.items) ? args.items : Array.isArray(args.data) ? args.data : [];
145
+ if(typeof mutateFetchedItemsRef.current =='function'){
146
+ const itx = mutateFetchedItemsRef.current(args.items);
147
+ if(Array.isArray(itx)){
148
+ args.items = args.data = itx;
149
+ }
150
+ }
151
+ if(typeof onFetchItemsRef.current ==='function'){
152
+ onFetchItemsRef.current({...args,context:{refresh},props});
153
+ }
154
+ hasRefreshedRef.current = true;
155
+ fetchedResultRef.current = args;
156
+ return fetchedResultRef.current;
157
+ }).catch((e)=>{
158
+ console.log(e," fetching list of data select table data ",foreignKeyColumn,foreignKeyTable)
159
+ });
160
+ },
161
+ showError : false,
162
+ swrOptions,
163
+ });
164
+ const isLoading = cIsLoading || isValidating;
165
+ const items = React.useMemo(()=>{
166
+ const fItems = isObj(fetchedItems)? fetchedItems: fetchedResultRef.current;
167
+ if(!isObj(fItems) || !Array.isArray(fItems.items)) return [];
168
+ return fItems.items;
169
+ },[fetchedItems]);
116
170
  React.useEffect(()=>{
117
171
  if(bindUpsert2RemoveEvents === false || !(foreignKeyTableStr)){
118
172
  return ()=>{}
119
173
  }
120
174
  const onUpsertData = ()=>{
121
- return isMounted()?context.refresh():undefined
175
+ return isMounted()?refresh():undefined
122
176
  };
123
177
  APP.on(actions.upsert(foreignKeyTableStr),onUpsertData);
124
178
  APP.on(actions.onRemove(foreignKeyTableStr),onUpsertData);
@@ -126,90 +180,16 @@ const TableDataSelectField = React.forwardRef(({foreignKeyColumn,foreignKeyLabel
126
180
  APP.off(actions.upsert(foreignKeyTableStr),onUpsertData);
127
181
  APP.off(actions.onRemove(foreignKeyTableStr),onUpsertData);
128
182
  };
129
- },[foreignKeyTableStr,bindUpsert2RemoveEvents])
130
- React.useEffect(()=>{
131
- context.refresh();
132
- },[]);
133
-
134
- let dat = isNonNullString(foreignKeyColumnValue)? {
135
- [foreignKeyColumn]:foreignKeyColumnValue,
136
- ...(isNonNullString(foreignKeyLabel) ? {[foreignKeyLabel]:foreignKeyColumnValue+", introuvable dans le système"}:{})
137
- } : null;
138
- const cFetch = typeof customFetchItem =='function' && customFetchItem;
139
- const fetchItems = (opts)=>{
140
- opts.showError = false;
141
- if(sortColumn){
142
- opts.sort = sort;
143
- }
144
- if(cFetch) return cFetch(queryPath,{...props,sort:{column:sortColumn,dir:sortDir},sortColumn,isUpdate,foreignKeyColumn,foreignKeyLabel,sortDir,foreignKeyTableObj:fKeyTable,foreignKeyTable,...opts});
145
- if(queryPath){
146
- return fetch(queryPath,opts);
147
- }
148
- };
149
- const context = {
150
- refresh : (force,cb)=>{
151
- if(!isMounted()) return;
152
- if(typeof beforeFetchItems ==='function' && beforeFetchItems({fetchOptions}) === false) return;
153
- let opts = Object.clone(fetchOptions);
154
- if(parseMangoQueries){
155
- opts.selector = filtersParseMangoQueries(opts.selector);
156
- opts = getFetchOptions(opts);
157
- delete opts.selector;
158
- } else {
159
- opts = {fetchOptions:opts};
160
- }
161
- const r = fetchItems(opts);
162
- if(r === false) return;
163
- setIsLoading(true);
164
- if(isPromise(r)){
165
- r.then((args)=>{
166
- if(Array.isArray(args)){
167
- args = {data : args};
168
- }
169
- if(!isObj(args)) {
170
- args = {items:[]}
171
- }
172
- let items = args.items = args.data = Array.isArray(args.items) ? args.items : Array.isArray(args.data) ? args.data : [];
173
- if(dat && isUpdate){
174
- if(isFunction(mutateFetchedItems)){
175
- items = mutateFetchedItems(items);
176
- }
177
- let hasFound = false;
178
- if(!isObjOrArray(items)) items = [];
179
- for(let i in items){
180
- if(isObj(items[i]) && items[i][foreignKeyColumn] == foreignKeyColumnValue){
181
- hasFound = true;
182
- break;
183
- }
184
- }
185
- if(!hasFound){
186
- if(Array.isArray(items)){
187
- items.push(dat);
188
- } else {
189
- items[foreignKeyColumnValue] = dat;
190
- }
191
- }
192
- }
193
- setItems(items);
194
- if(onFetchItems){
195
- onFetchItems({data:items,items,context,props});
196
- }
197
- hasRefreshedRef.current = true;
198
- }).catch((e)=>{
199
- console.log(e," fetching list of data select table data ",foreignKeyColumn,foreignKeyTable)
200
- }).finally((e)=>{
201
- setIsLoading(false);
202
- })
203
- } else {
204
- setIsLoading(false);
205
- }
206
- }
183
+ },[foreignKeyTableStr,bindUpsert2RemoveEvents]);
184
+ if(hasErrors) {
185
+ console.error(...errors);
186
+ return null;
207
187
  }
208
188
  dropdownActions = isObj(dropdownActions)? {...dropdownActions} : isArray(dropdownActions)? [...dropdownActions] : []
209
189
  const isDropdonwsActionsArray = isArray(dropdownActions);
210
190
  const refreshItem = {
211
191
  text : 'Rafraichir',
212
- onPress : context.refresh,
192
+ onPress : refresh,
213
193
  icon : 'refresh',
214
194
  }
215
195
  if(isDropdonwsActionsArray){
@@ -270,18 +250,9 @@ const TableDataSelectField = React.forwardRef(({foreignKeyColumn,foreignKeyLabel
270
250
  ttitle = txt && tt ? "{0} [{1}]".sprintf(txt,tt) : tt || txt;
271
251
  }
272
252
  dialogProps.title = ttitle;
273
- const showAdd = React.useMemo(()=>{
274
- if(isFilter || !foreignKeyTable) return false;
275
- if(typeof canShowAdd ==='function'){
276
- return !!canShowAdd({...props,table:foreignKeyTable,foreignKeyColumn,foreignKeyLabel,sortDir,foreignKeyTableObj:fKeyTable,foreignKeyTable})
277
- } else if(Auth[isStructData?"isStructDataAllowed":"isTableDataAllowed"]({table:foreignKeyTable,action:'create'})){
278
- return !!defaultVal(customShowAdd,true);
279
- }
280
- return false;
281
- },[isFilter,foreignKeyTable,customShowAdd]);
282
253
  return <Dropdown
283
254
  {...props}
284
- items = {stateItems}
255
+ items = {items}
285
256
  isFilter = {isFilter}
286
257
  showAdd = {showAdd}
287
258
  isLoading = {isLoading}
@@ -297,7 +268,7 @@ const TableDataSelectField = React.forwardRef(({foreignKeyColumn,foreignKeyLabel
297
268
  ref = {ref}
298
269
  defaultValue = {foreignKeyColumnValue}
299
270
  dropdownActions = {dropdownActions}
300
- context = {context}
271
+ context = {{refresh}}
301
272
  itemValue = {(p,...rest) => {
302
273
  if(typeof props.itemValue ==='function'){
303
274
  return props.itemValue(p,...rest);
@@ -323,7 +294,7 @@ const TableDataSelectField = React.forwardRef(({foreignKeyColumn,foreignKeyLabel
323
294
  return rItem(p,...rest);
324
295
  }}
325
296
  onAdd = {(args)=>{
326
- onAddProps = defaultObj(isFunction(onAddProps)? onAddProps.call(context,{context,foreignKeyTable,dbName,props}) : onAddProps);
297
+ onAddProps = defaultObj(isFunction(onAddProps)? onAddProps({context:{refresh},foreignKeyTable,dbName,props}) : onAddProps);
327
298
  if(typeof onAdd =='function'){
328
299
  return onAdd({...args,...onAddProps});
329
300
  }
@@ -334,6 +305,7 @@ const TableDataSelectField = React.forwardRef(({foreignKeyColumn,foreignKeyLabel
334
305
 
335
306
  TableDataSelectField.propTypes = {
336
307
  ...Dropdown.propTypes,
308
+ swrOptions : PropTypes.object,//les options supplémentaires à passer à la fonction swr
337
309
  /*** permet de faire le mappage entre les foreignKeyLabel et les type correspondants */
338
310
  foreignKeyLabelRenderers : PropTypes.objectOf(PropTypes.oneOfType([
339
311
  PropTypes.string, //représente le type de données associée à la colone dont le nom la clé
@@ -343,7 +315,9 @@ TableDataSelectField.propTypes = {
343
315
  bindUpsert2RemoveEvents : PropTypes.bool,//si le composant écoutera l'évènement de rafraichissement des données
344
316
  onAdd : PropTypes.func, //({})=>, la fonction appelée lorsque l'on clique sur le bouton add
345
317
  canShowAdd : PropTypes.func, //({foreignKeyTable,foreignKeyColumn})=><boolean> la fonction permettant de spécifier si l'on peut afficher le bouton showAdd
346
- mutateFetchedItems : PropTypes.func, //la fonction permettant d'effectuer une mutation sur l'ensemble des donnéees récupérées à distance
318
+ //la fonction permettant d'effectuer une mutation sur l'ensemble des donnéees récupérées à distance
319
+ //si le résultat de cette fonction est un array, alors le array en question représentera les nouvelles valeurs des items à considérer
320
+ mutateFetchedItems : PropTypes.func,
347
321
  fetchItems : PropTypes.func,//la fonction de rappel à utiliser pour faire une requête fetch permettant de selectionner les données à distance
348
322
  foreignKeyTable : PropTypes.string, //le nom de la fKeyTable data à laquelle se reporte le champ
349
323
  fetchItemsPath : PropTypes.string, //le chemin d'api pour récupérer les items des données étrangères en utilisant la fonction fetch
@@ -110,12 +110,24 @@ const Provider = ({children,getTableData,handleHelpScreen,navigation,swrConfig,a
110
110
 
111
111
  ///swr config settings
112
112
  ///garde pour chaque écran sa date de dernière activité
113
+ ///@see : https://swr.vercel.app/docs/api
113
114
  const screensRef = React.useRef({});//la liste des écrans actifs
114
115
  const activeScreenRef = React.useRef('');
115
116
  const appStateRef = React.useRef({});
116
117
  const swrRefreshTimeout = defaultNumber(swrConfig?.refreshTimeout,SWR_REFRESH_TIMEOUT)
117
118
  swrConfig = extendObj({
118
119
  provider: () => new Map(),
120
+ dedupingInterval : swrRefreshTimeout,
121
+ errorRetryInterval : Math.max(swrRefreshTimeout*2,SWR_REFRESH_TIMEOUT),
122
+ errorRetryCount : 5,
123
+ revalidateOnMount : true,//enable or disable automatic revalidation when component is mounted
124
+ revalidateOnFocus : true, //automatically revalidate when window gets focused (details)
125
+ revalidateOnReconnect : true, //automatically revalidate when the browser regains a network
126
+ refreshInterval : swrRefreshTimeout, //5 minutes : Disabled by default: refreshInterval = 0, If set to a number, polling interval in milliseconds, If set to a function, the function will receive the latest data and should return the interval in milliseconds
127
+ refreshWhenHidden : false, //polling when the window is invisible (if refreshInterval is enabled)
128
+ refreshWhenOffline : false, //polling when the browser is offline (determined by navigator.onLine)
129
+ shouldRetryOnError : false, //retry when fetcher has an error
130
+ dedupingInterval : swrRefreshTimeout,//dedupe requests with the same key in this time span in milliseconds
119
131
  refreshWhenOffline : canFetchOffline,
120
132
  isOnline() {
121
133
  /* Customize the network state detector */
@@ -135,13 +147,6 @@ const Provider = ({children,getTableData,handleHelpScreen,navigation,swrConfig,a
135
147
  return false;
136
148
  }
137
149
  return true;
138
- const date = screensRef.current[screen];
139
- const diff = new Date().getTime() - date.getTime();
140
- const ret = diff >= swrRefreshTimeout ? true : false;
141
- if(ret){
142
- screensRef.current[screen] = new Date();
143
- }
144
- return ret;
145
150
  },
146
151
  initFocus(callback) {
147
152
  let appState = AppState.currentState
@@ -211,6 +211,9 @@ export default class TableDataScreenComponent extends FormDataScreen{
211
211
  return defaultStr(this.props.sessionName,"table-form-data"+this.getTableName())
212
212
  }
213
213
  prepareField(a,...args){
214
+ if(isObj(a?.field) && !this.canRenderActions()){
215
+ a.field.disabled = true;
216
+ }
214
217
  if(typeof this.props.prepareField =='function'){
215
218
  return this.props.prepareField(a,...args);
216
219
  }
@@ -268,6 +271,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
268
271
  } = this.prepareComponentProps({...props,tableName,context:this,fields:extendObj(true,{},this.fields,props.fields),isUpdated,isUpdate:isUpdated,data,datas,currentIndex});
269
272
  const sessionName = this.getSessionName();
270
273
  const generatedColumnsProps = this.getGeneratedColumnsProperties();
274
+ const canRenderActions = this.canRenderActions({...props,...rest});
271
275
  ///on effectue une mutator sur le champ en cours de modification
272
276
  Object.map(preparedFields,(field,i,counterIndex)=>{
273
277
  const currentField = isObj(field)?Object.clone(field):field;
@@ -307,6 +311,9 @@ export default class TableDataScreenComponent extends FormDataScreen{
307
311
  this.primaryKeyFields[columnField] = true;
308
312
  }
309
313
  const isPrimary = this.primaryKeyFields[columnField] && true || false;
314
+ if(!canRenderActions){
315
+ currentField.disabled = true;
316
+ }
310
317
  const f = this.prepareField(cArgs);
311
318
  if(f === false) {
312
319
  delete fields[i];
@@ -705,6 +712,9 @@ export default class TableDataScreenComponent extends FormDataScreen{
705
712
  return this.setState({data:currentData,datas:[],hasManyData:false},callback);
706
713
  }
707
714
  }
715
+ setCurrentData(...args){
716
+ return this.reloadCurrentData(...args);
717
+ }
708
718
  doSave ({goBack,data,action}){
709
719
  action = defaultStr(action,this.clickedEl);
710
720
  const cb = ()=>{
@@ -858,6 +868,23 @@ export default class TableDataScreenComponent extends FormDataScreen{
858
868
  getTableName(){
859
869
  return this.tableName;
860
870
  }
871
+ triggerUpsert(...rest){
872
+ const tableName = defaultStr(this.getTableName(),this.props.tableName,this.props.table);
873
+ if(tableName){
874
+ return APP.trigger(cActions.upsert(tableName),...rest);
875
+ }
876
+ return false;
877
+ }
878
+ triggerDelete(...rest){
879
+ const tableName = defaultStr(this.getTableName(),this.props.tableName,this.props.table);
880
+ if(tableName){
881
+ return APP.trigger(cActions.remove(tableName),...rest);
882
+ }
883
+ return false;
884
+ }
885
+ triggerRemove(...args){
886
+ return this.triggerDelete(...args);
887
+ }
861
888
  getTableText(){
862
889
  const tableObj = this.getTableObj();
863
890
  return defaultStr(tableObj?.text,tableObj?.label);
@@ -1,7 +1,7 @@
1
1
  module.exports = {
2
2
  "@fto-consult/expo-ui": {
3
3
  "name": "@fto-consult/expo-ui",
4
- "version": "7.16.9",
4
+ "version": "7.17.9",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/borispipo/expo-ui.git"
@@ -49,7 +49,7 @@ module.exports = {
49
49
  "license": "MIT"
50
50
  },
51
51
  "@fto-consult/common": {
52
- "version": "4.1.4",
52
+ "version": "4.2.1",
53
53
  "url": "https://github.com/borispipo/common#readme",
54
54
  "license": "ISC"
55
55
  },
@@ -263,7 +263,7 @@ module.exports = {
263
263
  "license": "MIT"
264
264
  },
265
265
  "react-native-paper": {
266
- "version": "5.11.6",
266
+ "version": "5.11.7",
267
267
  "url": "https://callstack.github.io/react-native-paper",
268
268
  "license": "MIT"
269
269
  },