@fto-consult/expo-ui 2.7.12 → 2.8.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/expo-ui-path.js CHANGED
@@ -6,26 +6,34 @@ const fs = require("fs");
6
6
  const path = require("path");
7
7
  const { hideBin } = require('yargs/helpers')
8
8
  const yargs = require('yargs/yargs');
9
+ let pathRef = {current:null};
10
+ const metroConfig = "metro.config";
9
11
  ///retourne le chemin vers le package @expo-ui
10
12
  module.exports = function (...args){
11
- const argv = yargs(hideBin(process.argv)).argv
12
- let isBuild = false;
13
- const expoUIPath = "@fto-consult/expo-ui";
14
- if(typeof argv == 'object' && argv && !Array.isArray(argv)){
13
+ const argv = yargs(hideBin(process.argv)).argv;
14
+ const suffix = path.join(...args);
15
+ const isMetroConfig = suffix && suffix.toLowerCase().includes(metroConfig);
16
+ let isBuild = isMetroConfig ? false : pathRef.current ? true : false;
17
+ let expoUIPath = isBuild ? pathRef.current : "@fto-consult/expo-ui";
18
+ if(isMetroConfig && typeof argv == 'object' && argv && !Array.isArray(argv)){
15
19
  for(let i in argv){
16
20
  let v = argv[i];
17
21
  if(typeof v !='string' || !v) continue;
18
22
  v = v.toLowerCase();
19
23
  i = (i+'').toLocaleLowerCase();
20
- if(i.includes("export") || v.includes('build') || v.includes('production') || v.includes('export') || v.includes('android')){
21
- isBuild = true;
22
- break;
24
+ if(i != '$0'){
25
+ if(v.includes('production') || v.includes('export') || v.includes('android')){
26
+ isBuild = true;
27
+ break;
28
+ }
23
29
  }
24
30
  }
25
31
  }
26
- const suffix = path.join(...args);
27
32
  const sep = path.sep;
28
33
  if(isBuild){
34
+ if(isMetroConfig){
35
+ pathRef.current = expoUIPath;
36
+ }
29
37
  const pp = suffix ? path.join(expoUIPath,suffix).replace(sep,"/") : expoUIPath;
30
38
  return pp;
31
39
  }
@@ -34,6 +42,9 @@ module.exports = function (...args){
34
42
  const rootPath = path.resolve(p,"..");
35
43
  const src = path.resolve(rootPath,"src");
36
44
  if(fs.existsSync(src) && fs.existsSync((path.resolve(rootPath,"babel.config.js")))){
45
+ if(isMetroConfig){
46
+ pathRef.current = path.resolve(p);
47
+ }
37
48
  return path.resolve(p,suffix).replace(sep,(sep+sep));
38
49
  }
39
50
  }
package/package.json CHANGED
@@ -1,115 +1,115 @@
1
- {
2
- "name": "@fto-consult/expo-ui",
3
- "version": "2.7.12",
4
- "description": "Bibliothèque de composants UI Expo,react-native",
5
- "main": "index.js",
6
- "resolutions": {
7
- "@expo/cli": "xxx"
8
- },
9
- "scripts": {
10
- "publish1": "npm publish --access=public",
11
- "unpublish": "npm -f unpublish @fto-consult/expo-ui",
12
- "build-web": "",
13
- "dev": "npx expo start -c --no-minify",
14
- "start": "npx expo start --dev --no-minify",
15
- "start-d": "npx expo start -c --no-dev --no-minify",
16
- "start-p": "npm run start-d",
17
- "expo-start-client": "npx expo start --dev --no-minify --dev-client",
18
- "start-m": "npx expo start - c--dev--no -minify",
19
- "android": "npx expo start --android -c",
20
- "ios": "npx expo start --ios",
21
- "web": "npx expo start --web",
22
- "web-c": "npx expo start --web -c",
23
- "eject": "expo eject",
24
- "emulator": "npm run android-emulator",
25
- "web-server": "npx serve web-build",
26
- "build-android": "eas build --clear-cache -p android --profile preview",
27
- "build-android-local": "eas build --platform android --local",
28
- "build-android-dist": "eas build --clear-cache -p android",
29
- "build-ios": "eas build --clear-cache -p ios --profile preview",
30
- "build-ios-dist": "eas build --clear-cache -p ios",
31
- "install-apk": "adb -s emulator-5554 install myapp.apk",
32
- "android-emulator": "emulator -avd EMULATOR",
33
- "flipper": "npx cross-env METRO_SERVER_PORT=19000 E:\\Studies\\react-native\\debugger\\Flipper-win\\Flipper.exe",
34
- "build-electron": "electron-webpack && electron-builder --dir -c.compression=store",
35
- "test:build": "electron-webpack && electron-builder --dir -c.compression=store -c.mac.identity=null",
36
- "compile-electron": "webpack --config ./electron/webpack.config.js",
37
- "compile-electron-p": "webpack --config ./electron/webpack.config.js --mode=production",
38
- "electron": "electron ./electron",
39
- "logcat": "adb -d logcat com.ftc.apps.salite1:E > errors.txt",
40
- "logcat-export": "adb -d logcat com.ftc.apps.salite1 *:S > logcat.txt",
41
- "electron-c": "npm run compile-electron && npm run electron",
42
- "electron-p": "npm run compile-electron-p && npm run electron",
43
- "update-app-version": "node ./update-app-version.js",
44
- "find-licenses": "node ./find-licenses.js",
45
- "fix-dependencies": "expo doctor --fix-dependencies",
46
- "delete-node-modules": "rimraf ./**/node_modules"
47
- },
48
- "repository": {
49
- "type": "git",
50
- "url": "git+https://github.com/borispipo/expo-ui.git"
51
- },
52
- "keywords": [
53
- "Expo",
54
- "React-Native"
55
- ],
56
- "author": "Boris Fouomene",
57
- "license": "ISC",
58
- "bugs": {
59
- "url": "https://github.com/borispipo/expo-ui/issues"
60
- },
61
- "homepage": "https://github.com/borispipo/expo-ui#readme",
62
- "dependencies": {
63
- "@babel/plugin-proposal-export-namespace-from": "^7.18.9",
64
- "@babel/preset-react": "^7.18.6",
65
- "@emotion/native": "^11.10.0",
66
- "@expo/html-elements": "^0.2.0",
67
- "@expo/metro-config": "^0.4.0",
68
- "@expo/vector-icons": "^13.0.0",
69
- "@expo/webpack-config": "^0.17.2",
70
- "@fto-consult/common": "^1.13.1",
71
- "@gorhom/portal": "^1.0.14",
72
- "@react-native-async-storage/async-storage": "~1.17.3",
73
- "@react-native-community/datetimepicker": "6.5.2",
74
- "@react-native-community/netinfo": "9.3.5",
75
- "@react-navigation/native": "^6.0.13",
76
- "@react-navigation/native-stack": "^6.9.1",
77
- "@shopify/flash-list": "1.3.1",
78
- "babel-plugin-inline-dotenv": "^1.7.0",
79
- "babel-plugin-module-resolver": "^4.1.0",
80
- "babel-plugin-transform-inline-environment-variables": "^0.4.4",
81
- "expo": "^47.0.8",
82
- "expo-camera": "~13.1.0",
83
- "expo-clipboard": "~4.0.1",
84
- "expo-font": "~11.0.1",
85
- "expo-image-picker": "~14.0.2",
86
- "expo-linking": "~3.2.3",
87
- "expo-sqlite": "~11.0.0",
88
- "expo-status-bar": "~1.4.2",
89
- "expo-system-ui": "~2.0.1",
90
- "expo-web-browser": "~12.0.0",
91
- "google-libphonenumber": "^3.2.31",
92
- "htmlparser2-without-node-native": "^3.9.2",
93
- "mongo-parse": "^2.1.0",
94
- "parent-package-json": "^2.0.1",
95
- "prop-types": "^15.8.1",
96
- "react": "18.1.0",
97
- "react-apexcharts": "^1.4.0",
98
- "react-content-loader": "^6.2.0",
99
- "react-dom": "18.1.0",
100
- "react-native": "0.70.5",
101
- "react-native-big-list": "^1.5.5",
102
- "react-native-gesture-handler": "~2.8.0",
103
- "react-native-paper": "^4.12.5",
104
- "react-native-paper-dates": "^0.9.2",
105
- "react-native-reanimated": "~2.12.0",
106
- "react-native-safe-area-context": "4.4.1",
107
- "react-native-screens": "~3.18.0",
108
- "react-native-svg": "13.4.0",
109
- "react-native-web": "~0.18.7",
110
- "react-native-webview": "11.23.1",
111
- "sharp-cli": "^2.1.0",
112
- "tippy.js": "^6.3.7",
113
- "yargs": "^17.1.1-candidate.0"
114
- }
115
- }
1
+ {
2
+ "name": "@fto-consult/expo-ui",
3
+ "version": "2.8.0",
4
+ "description": "Bibliothèque de composants UI Expo,react-native",
5
+ "main": "index.js",
6
+ "resolutions": {
7
+ "@expo/cli": "xxx"
8
+ },
9
+ "scripts": {
10
+ "publish1": "npm publish --access=public",
11
+ "unpublish": "npm -f unpublish @fto-consult/expo-ui",
12
+ "build-web": "",
13
+ "dev": "npx expo start -c --no-minify",
14
+ "start": "npx expo start --dev --no-minify",
15
+ "start-d": "npx expo start -c --no-dev --no-minify",
16
+ "start-p": "npm run start-d",
17
+ "expo-start-client": "npx expo start --dev --no-minify --dev-client",
18
+ "start-m": "npx expo start - c--dev--no -minify",
19
+ "android": "npx expo start --android -c",
20
+ "ios": "npx expo start --ios",
21
+ "web": "npx expo start --web",
22
+ "web-c": "npx expo start --web -c",
23
+ "eject": "expo eject",
24
+ "emulator": "npm run android-emulator",
25
+ "web-server": "npx serve web-build",
26
+ "build-android": "eas build --clear-cache -p android --profile preview",
27
+ "build-android-local": "eas build --platform android --local",
28
+ "build-android-dist": "eas build --clear-cache -p android",
29
+ "build-ios": "eas build --clear-cache -p ios --profile preview",
30
+ "build-ios-dist": "eas build --clear-cache -p ios",
31
+ "install-apk": "adb -s emulator-5554 install myapp.apk",
32
+ "android-emulator": "emulator -avd EMULATOR",
33
+ "flipper": "npx cross-env METRO_SERVER_PORT=19000 E:\\Studies\\react-native\\debugger\\Flipper-win\\Flipper.exe",
34
+ "build-electron": "electron-webpack && electron-builder --dir -c.compression=store",
35
+ "test:build": "electron-webpack && electron-builder --dir -c.compression=store -c.mac.identity=null",
36
+ "compile-electron": "webpack --config ./electron/webpack.config.js",
37
+ "compile-electron-p": "webpack --config ./electron/webpack.config.js --mode=production",
38
+ "electron": "electron ./electron",
39
+ "logcat": "adb -d logcat com.ftc.apps.salite1:E > errors.txt",
40
+ "logcat-export": "adb -d logcat com.ftc.apps.salite1 *:S > logcat.txt",
41
+ "electron-c": "npm run compile-electron && npm run electron",
42
+ "electron-p": "npm run compile-electron-p && npm run electron",
43
+ "update-app-version": "node ./update-app-version.js",
44
+ "find-licenses": "node ./find-licenses.js",
45
+ "fix-dependencies": "expo doctor --fix-dependencies",
46
+ "delete-node-modules": "rimraf ./**/node_modules"
47
+ },
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "git+https://github.com/borispipo/expo-ui.git"
51
+ },
52
+ "keywords": [
53
+ "Expo",
54
+ "React-Native"
55
+ ],
56
+ "author": "Boris Fouomene",
57
+ "license": "ISC",
58
+ "bugs": {
59
+ "url": "https://github.com/borispipo/expo-ui/issues"
60
+ },
61
+ "homepage": "https://github.com/borispipo/expo-ui#readme",
62
+ "dependencies": {
63
+ "@babel/plugin-proposal-export-namespace-from": "^7.18.9",
64
+ "@babel/preset-react": "^7.18.6",
65
+ "@emotion/native": "^11.10.0",
66
+ "@expo/html-elements": "^0.2.0",
67
+ "@expo/metro-config": "^0.4.0",
68
+ "@expo/vector-icons": "^13.0.0",
69
+ "@expo/webpack-config": "^0.17.2",
70
+ "@fto-consult/common": "^1.14.15",
71
+ "@gorhom/portal": "^1.0.14",
72
+ "@react-native-async-storage/async-storage": "~1.17.3",
73
+ "@react-native-community/datetimepicker": "6.5.2",
74
+ "@react-native-community/netinfo": "9.3.5",
75
+ "@react-navigation/native": "^6.0.13",
76
+ "@react-navigation/native-stack": "^6.9.1",
77
+ "@shopify/flash-list": "1.3.1",
78
+ "babel-plugin-inline-dotenv": "^1.7.0",
79
+ "babel-plugin-module-resolver": "^4.1.0",
80
+ "babel-plugin-transform-inline-environment-variables": "^0.4.4",
81
+ "expo": "^47.0.8",
82
+ "expo-camera": "~13.1.0",
83
+ "expo-clipboard": "~4.0.1",
84
+ "expo-font": "~11.0.1",
85
+ "expo-image-picker": "~14.0.2",
86
+ "expo-linking": "~3.2.3",
87
+ "expo-sqlite": "~11.0.0",
88
+ "expo-status-bar": "~1.4.2",
89
+ "expo-system-ui": "~2.0.1",
90
+ "expo-web-browser": "~12.0.0",
91
+ "google-libphonenumber": "^3.2.31",
92
+ "htmlparser2-without-node-native": "^3.9.2",
93
+ "mongo-parse": "^2.1.0",
94
+ "parent-package-json": "^2.0.1",
95
+ "prop-types": "^15.8.1",
96
+ "react": "18.1.0",
97
+ "react-apexcharts": "^1.4.0",
98
+ "react-content-loader": "^6.2.0",
99
+ "react-dom": "18.1.0",
100
+ "react-native": "0.70.5",
101
+ "react-native-big-list": "^1.5.5",
102
+ "react-native-gesture-handler": "~2.8.0",
103
+ "react-native-paper": "^4.12.5",
104
+ "react-native-paper-dates": "^0.9.2",
105
+ "react-native-reanimated": "~2.12.0",
106
+ "react-native-safe-area-context": "4.4.1",
107
+ "react-native-screens": "~3.18.0",
108
+ "react-native-svg": "13.4.0",
109
+ "react-native-web": "~0.18.7",
110
+ "react-native-webview": "11.23.1",
111
+ "sharp-cli": "^2.1.0",
112
+ "tippy.js": "^6.3.7",
113
+ "yargs": "^17.1.1-candidate.0"
114
+ }
115
+ }
package/src/auth/Login.js CHANGED
@@ -86,7 +86,7 @@ export default function LoginComponent(props){
86
86
  },1000)
87
87
  }
88
88
  },[withPortal])
89
- const {header,withScrollView:customWithScrollView,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,beforeSubmit:beforeSubmitForm,canSubmit:canSubmitForm,onStepChange,...loginProps} = defaultObj(getProps({
90
90
  ...state,
91
91
  setState,
92
92
  state,
@@ -119,6 +119,7 @@ export default function LoginComponent(props){
119
119
  * par défaut, on envoie les données lorssqu'on est à l'étappe 2
120
120
  * **/
121
121
  const canSubmit = typeof canSubmitForm =='function'? canSubmitForm : ({step})=>step >= 2;
122
+ const beforeSubmit = typeof beforeSubmitForm =='function'? beforeSubmitForm : x=> true;
122
123
  const goToNext = ()=>{
123
124
  let step = state.step;
124
125
  const data = getData();
@@ -149,7 +150,7 @@ export default function LoginComponent(props){
149
150
  nextButtonRef.current?.enable();
150
151
  }
151
152
  if(step > 1){
152
- if(canSubmit(args)){
153
+ if(canSubmit(args) && beforeSubmit(args) !== false){
153
154
  ///pour modifier automatiquement la données à mettre à jour
154
155
  if(typeof mutateData =='function'){
155
156
  mutateData(data);
@@ -178,7 +179,7 @@ export default function LoginComponent(props){
178
179
  else {
179
180
  loginFields[i] = Object.clone(field);
180
181
  hasLoginFields = true;
181
- if("autoFocusOnStep" in loginFields[i]){
182
+ if("autoFocusOnStep" in loginFields[i] && typeof loginFields[i].autoFocus !=='boolean'){
182
183
  loginFields[i].autoFocus = !!loginFields[i].autoFocusOnStep;
183
184
  }
184
185
  }
@@ -11,7 +11,7 @@ import {notify,showConfirm} from "$ecomponents/Dialog";
11
11
  import Label from "$ecomponents/Label";
12
12
  import Image from "$ecomponents/Image";
13
13
  import Icon,{COPY_ICON} from "$ecomponents/Icon";
14
- import filterUtils from "$ecomponents/Filter/utils";
14
+ import filterUtils from "$cfilters";
15
15
  import Hashtag from "$ecomponents/Hashtag";
16
16
  import {sortBy,isDecimal,extendObj,isObjOrArray,defaultNumber,defaultStr,isFunction,defaultBool,defaultArray,defaultObj,isNonNullString,defaultDecimal} from "$utils";
17
17
  import {Datagrid as DatagridContentLoader} from "$ecomponents/ContentLoader";
@@ -900,7 +900,7 @@ export default class CommonDatagridComponent extends AppComponent {
900
900
  field = header.field = defaultStr(header.field,field,headerIndex);
901
901
  delete restCol.filter;
902
902
 
903
- const type = defaultStr(header.type).toLowerCase();
903
+ const type = defaultStr(header.jsType,header.type,"text").toLowerCase();
904
904
  sortType = defaultStr(sortType,type).toLowerCase();
905
905
  width = defaultDecimal(width);
906
906
  if(width <COLUMN_WIDTH/2){
@@ -929,6 +929,7 @@ export default class CommonDatagridComponent extends AppComponent {
929
929
  });
930
930
  restCol.field = header.field;
931
931
  restCol.label = defaultStr(header.text,header.label) ;
932
+ restCol.type = type;
932
933
  if(!restCol.label){
933
934
  console.error(header," has not label or text in datagrid",columns,this.props)
934
935
  }
@@ -957,6 +958,7 @@ export default class CommonDatagridComponent extends AppComponent {
957
958
  delete restCol.sortable;
958
959
  filterProps = {
959
960
  ...restCol,
961
+ type,
960
962
  columnIndex,
961
963
  visibleColumnIndex,
962
964
  sortable:isColumnSortable,
@@ -986,6 +988,7 @@ export default class CommonDatagridComponent extends AppComponent {
986
988
  }
987
989
  this.prepareColumn({
988
990
  visible,
991
+ type,
989
992
  columnIndex,
990
993
  visibleColumnIndex,
991
994
  sortable:isColumnSortable,
@@ -1493,6 +1496,7 @@ export default class CommonDatagridComponent extends AppComponent {
1493
1496
  if(!isObj(rowData)) return {render:null,extra:{}};
1494
1497
  let _render = null;
1495
1498
  columnDef = defaultObj(columnDef);
1499
+ let _type = defaultStr(columnDef.jsType,columnDef.type).trim().toLowerCase();
1496
1500
  if(this.isSelectableColumn(columnDef,columnField)){
1497
1501
  rowKey = rowKey ? rowKey : this.getRowKey(rowData,rowIndex);
1498
1502
  return {render :handleSelectableColumn === false ? null : this.renderSelectableCheckboxCell({
@@ -1528,7 +1532,6 @@ export default class CommonDatagridComponent extends AppComponent {
1528
1532
  _render = defaultDecimal(columnDef.multiplicater({...renderArgs,value:rowData[columnField]}),rowData[columnField]);
1529
1533
  } else {
1530
1534
  _render = defaultValue;
1531
- let _type = defaultStr(columnDef.type).trim().toLowerCase();
1532
1535
  if(defaultStr(columnDef.format).toLowerCase() === 'hashtag'){
1533
1536
  _render = <Hashtag>{_render}</Hashtag>
1534
1537
  } else if(typeof columnDef.render === "function"){
@@ -2,7 +2,7 @@
2
2
 
3
3
  import DateLib from "$lib/date";
4
4
  import {isNonNullString,defaultStr,isNullOrEmpty,debounce,uniqid} from "$utils";
5
- import {regexParser,regexActions,getFilterStateValues} from "./utils";
5
+ import {regexParser,regexActions,operators as _operators,actions as _actions,periodActions, inActions as _inActions,getFilterStateValues,getSessionData,setSessionData} from "$cfilters";
6
6
  import {parseDecimal} from "$ecomponents/TextField";
7
7
  import notify from "$notify";
8
8
  import PropTypes from "prop-types";
@@ -15,41 +15,12 @@ import React,{Component as AppComponent} from "$react";
15
15
  import theme from "$theme";
16
16
  import {isMobileMedia} from "$cplatform/dimensions";
17
17
  import { ActivityIndicator } from "react-native-paper";
18
- import { getSessionData,setSessionData } from "./session";
19
18
  import DialogProvider from "$components/Form/FormData/DialogProvider";
20
19
 
21
20
  const manualRunKey = "manual-run";
22
21
 
23
- export * from "./utils";
22
+ export * from "$cfilters";
24
23
 
25
- const _actions = {
26
- '$eq' : 'Egal à',
27
- "$ne" : 'Défférent de',
28
- '$gt' : 'Supérieur à',
29
- '$gte' : 'Supérieur ou égal',
30
- '$lt' : 'Inférieur à',
31
- '$lte' : 'Inférieur où égal à',
32
- }
33
-
34
- const _inActions = {
35
- '$in' :'Est inc ds la liste', //Array of JSON values The document field must exist in the list provided.
36
- '$nin' : 'N\'est pas inc ds la liste', //Array of JSON values The document field not must exist in the list provided.
37
- }
38
-
39
-
40
- const _operators = {
41
- '$and' : 'Et', //Array Matches if all the selectors in the array match.
42
- '$or' : 'Ou', //Array Matches if any of the selectors in the array match. All selectors must use the same index.
43
- }
44
-
45
- const periodActions = {
46
- $yesterday : "Hier",
47
- $today:"Aujourd'hui",
48
- $prevWeek:"Semaine passée",
49
- $week:'Cette semaine',
50
- $month:'Ce mois',
51
- $period:"Période"
52
- }
53
24
 
54
25
  /***** Coposant Filter, pour les filtres de données */
55
26
  export default class Filter extends AppComponent {
@@ -863,7 +863,7 @@ export default class Field extends AppComponent {
863
863
  delete rest.archivable;
864
864
 
865
865
  this.___formattedField = undefined;
866
- let _type = this.type = defaultStr(this.props.type,this.type,"text").trim().toLowerCase();
866
+ let _type = this.type = defaultStr(this.props.jsType,this.props.type,this.type,"text").trim().toLowerCase();
867
867
  format = defaultStr(format).toLowerCase().trim();
868
868
  tooltip = defaultVal(tooltip,title);
869
869
 
@@ -959,6 +959,7 @@ Field.propTypes = {
959
959
  PropTypes.node,
960
960
  PropTypes.func,
961
961
  ]),
962
+ jsType : PropTypes.string,
962
963
  usePlaceholderWhenEmpty : PropTypes.bool,//si la valeur du placeholder sera utilée, lorsque la valeur du champ de type formatable est nulle ou égale à la valeur vide
963
964
  responsive : PropTypes.bool,
964
965
  responsiveProps : PropTypes.object,
@@ -191,7 +191,7 @@ export default class FormDataComponent extends AppComponent{
191
191
  content.push(<Divider key = {index} style={theme.styles.w100}/>)
192
192
  } else if(isObj(field) && field.form !== false) {
193
193
  const name = defaultStr(field.name,field.field,index);
194
- const type = defaultStr(field.type,"text").trim().toLowerCase().replaceAll("_","");
194
+ const type = defaultStr(field.jsType,field.type,"text").trim().toLowerCase().replaceAll("_","");
195
195
  const Component = componentTypes[type] || componentTypes.default;
196
196
  let {defaultValue,useDefaultValueFromData,hidden,renderFormDataField,getMediaQueryStyle,printLabels,queryLimit,selected,value,visible,dataFilesInterest,perm,ignore,form,responsiveProps:customResponsiveProps,...rest} = field;
197
197
  rest = Object.assign({},rest);
@@ -61,12 +61,16 @@ const FontIcon = React.forwardRef(({icon,name,testID,color,iconStyle,backgroundC
61
61
  console.warn("Icone non définie pour le composant FontIcon, icon [{0}], merci de spécifier une icone supportée par la liste du module https://github.com/expo/vector-icons/MaterialCommunityIcons".sprintf(icon),props);
62
62
  return null;
63
63
  }
64
- const iconName = icon.ltrim("")
64
+ const iconName = icon.ltrim("material-")
65
+ .ltrim("fa-").ltrim("ant-").ltrim("fontisto-")
66
+ .ltrim("foundation-").ltrim("ionic-").ltrim("octicons-")
67
+ .ltrim("simple-line-").ltrim("zocial-").trim();
68
+
65
69
  return <Icon {...props}
66
70
  ref = {ref}
67
71
  testID = {testID}
68
72
  color={color}
69
- name = {icon}
73
+ name = {iconName}
70
74
  backgroundColor = {backgroundColor}
71
75
  />
72
76
  });
@@ -94,7 +98,7 @@ export const isIcon = (name,iconSet)=>{
94
98
  if(!isNonNullString(name) || !isNonNullString(iconSet)) return false;
95
99
  name = name.toLowerCase();
96
100
  iconSet = iconSet.toLowerCase().trim();
97
- return name.startsWith(iconSet+"-") || name.startsWith(iconSet+"s"+"-") ? true : false;
101
+ return name.startsWith(iconSet+"-") /*|| name.startsWith(iconSet+"s"+"-")*/ ? true : false;
98
102
  }
99
103
 
100
104
  export default theme.withStyles(FontIcon,{displayName:FontIcon.displayName,mode:'normal'});
@@ -160,7 +160,7 @@ const TableComponent = React.forwardRef(({containerProps,renderEmpty,isRowSelect
160
160
  const scrollContentContainerStyle = {flex:1,width:listWidth,minWidth:totalWidths,height:'100%'};
161
161
  const scrollEventThrottle = isMobileNative()?200:50;
162
162
  const scrollViewFlexGrow = {flexGrow:0};
163
- const maxScrollheight = f.length && fFilters.length ? 170 : f.length || fFilters.length ? 120 : 80;
163
+ const maxScrollheight = f.length && fFilters.length ? 170 : f.length ?120 : fFilters.length ? 140 : 80;
164
164
  const allScrollViewProps = {
165
165
  scrollEventThrottle,
166
166
  horizontal : true,
@@ -28,8 +28,8 @@ export const getItems = (force)=>{
28
28
  r.push(item);
29
29
  }
30
30
  })
31
- r.push({divider:true});
32
31
  if(handleHelp){
32
+ r.push({divider:true});
33
33
  const dataHelp = {
34
34
  key : 'dataHelp',
35
35
  label : 'Aide',
@@ -1,18 +0,0 @@
1
- import session from "$session";
2
- import {getLoggedUserCode} from "$cauth";
3
- const sKey = "FILTER-ITEM-KEY";
4
- const sessionKey = ()=> defaultStr(getLoggedUserCode())+"-"+sKey;
5
- import {defaultObj,defaultStr,isNonNullString} from "$utils";
6
-
7
- export const getSessionData = (key)=>{
8
- const data = defaultObj(session.get(sessionKey()));
9
- return isNonNullString(key)? data [key] : data;
10
- }
11
- export const setSessionData = (key,value)=>{
12
- const data = getSessionData();
13
- if(isNonNullString(key)){
14
- data[key] = value;
15
- return session.set(sessionKey(),data);
16
- }
17
- return false;
18
- }
@@ -1,552 +0,0 @@
1
-
2
- import {isNonNullString,defaultStr,defaultArray,isObjOrArray,isObj} from "$utils";
3
- import DateLib from "$date";
4
- import mangoParser from "mongo-parse";
5
-
6
- export const filterTextTypes = ['text','number','email','search','tel','url','password',"id","idfield",'piecefield','piece'];
7
-
8
- export const regexActions = {
9
- $regexequals : 'Egal à',
10
- $regexcontains : 'Contient',
11
- $regexnotcontains : 'Ne contient pas',
12
- $regexnotequals : 'Différent de',
13
- $regexstartswith : 'Commence par',
14
- $regexendswith : 'Se termine par'
15
- }
16
- export const escapeRegexChars = (value)=>{
17
- //if(value === undefined || value ===null || value === '' || value ==='undefined') return '';
18
- //value+='';
19
- if(!isNonNullString(value)) return '';
20
- let escapeChars = ['!', '^', '$', '(', ')', '[', ']', '{', '}', '?', '+', '*', '.', '/', '\\', '|']
21
- for(var i in escapeChars){
22
- value.replace(escapeChars[i],'\\'+escapeChars[i]);
23
- }
24
- return value.toString();
25
- }
26
-
27
- export const getFilterStateValues = (state)=>{
28
- state = defaultObj(state);
29
- const r = {};
30
- ['defaultValue','action','actions','operator','operators','ignoreCase','value','manualRun'].map((v)=>{
31
- r[v] = state[v];
32
- })
33
- return r;
34
-
35
- }
36
-
37
- /**** si le filtre peut être pris en compte */
38
- export const canHandleFilter = (f)=>{
39
- if(!isObj(f)) return false;
40
- if(!isNonNullString(f.operator) || !isNonNullString(f.action)) {
41
- return false;
42
- }
43
- if(f.value === undefined || f.value === 'undefined' || f.value ==='' || f.value ===null) {
44
- return false;
45
- }
46
- if(f.value instanceof RegExp){
47
- return true;
48
- }
49
- if(isObjOrArray(f.value) && Object.size(f.value,true) <=0) return false;
50
- return true;
51
-
52
- }
53
-
54
- export const regexExpressions = {
55
- notcontains : {
56
- left : "^((?!(",
57
- right : ")).)*$",
58
- /***@see : https://www.w3schools.com/sql/sql_like.asp */
59
- sql : (string)=>{
60
- return "%"+defaultStr(string).ltrim("%").rtrim("%")+"%";
61
- }
62
- },
63
- notequals : {
64
- left : "^(?!",
65
- right : "$).*$",
66
- },
67
- equals : {
68
- left : "/^",
69
- right : '$/'
70
- },
71
- startswith : {
72
- left : "/^",
73
- right : '/',
74
- sql : (string)=>{
75
- return defaultStr(string).rtrim("%")+"%";
76
- }
77
- },
78
- endswith : {
79
- left : "",
80
- right : '$/',
81
- sql : (string)=>{
82
- return "%"+defaultStr(string).ltrim("%");
83
- }
84
- },
85
- contains : {
86
- left : "/",
87
- right : '/',
88
- sql : (string)=>{
89
- return "%"+defaultStr(string).ltrim("%").rtrim("%")+"%";
90
- }
91
- },
92
- }
93
- /**** prend en paramètre une chaine de caractère et un nom d'opérateur et génère
94
- * la chaine de caracètre mango regex correspondant
95
- */
96
- const toMangoRegex = (val,operator)=>{
97
- if(!isNonNullString(val) || !isNonNullString(operator) || !regexExpressions[operator]) return "";
98
- const rOp = regexExpressions[operator];
99
- return rOp.left+escapeRegexChars(val)+rOp.right;
100
- }
101
- export const regexParser = {
102
- equals : (val)=> {
103
- return toMangoRegex(val,"equals");
104
- },
105
- startswith : (val) => {
106
- return toMangoRegex(val,"startswith");
107
- },
108
- endswith : (val) => {
109
- return toMangoRegex(val,"endswith");
110
- },
111
- contains : (val) => {
112
- return toMangoRegex(val,"contains");
113
- },
114
- notequals : (val) => {
115
- return toMangoRegex(val,"notequals");
116
- },
117
- notcontains : (val) =>{
118
- return toMangoRegex(val,"notcontains");
119
- }
120
- }
121
- /*** prend une expression regulière et le convertis en operateur, valeur
122
- * @param {string} la valeur otenue au format regex
123
- */
124
- export const regexDeparser = (regexValue)=>{
125
- if(!regexValue) return null;
126
- regexValue = regexValue.toString();
127
- if(regexValue.endsWith("/i")){
128
- regexValue = regexValue.rtrim("/i")+"/";
129
- }
130
- if(!isNonNullString(regexValue)) return null;
131
- for(let i in regexExpressions){
132
- const p = regexExpressions[i];
133
- let rVal = regexValue.ltrim("/").rtrim("/");
134
- const pLeft = p.left.ltrim("/"),pRight = p.right.rtrim("/");
135
- if(rVal.startsWith(pLeft) && rVal.endsWith(pRight)){
136
- return {
137
- operator : i,
138
- value : rVal.ltrim(pLeft).rtrim(pRight),
139
- regexValue : rVal,
140
- }
141
- }
142
- }
143
- return null;
144
- }
145
- export const matchPouchDBOperator = (operator,value)=>{
146
- if(!isNonNullString(operator)) return null;
147
- if(!(value) && !isDecimal(value)) return null;
148
- switch(operator){
149
- case "MATCH":
150
- if(isDecimal(value)) value +="";
151
- return {operator:"$regex",value:RegExp(defaultStr(regexParser.contains(value)).ltrim("/").rtrim("/"),'i')}
152
- case "NOTMATCH":
153
- if(isDecimal(value)) value +="";
154
- return {operator:"$regex",value:RegExp(defaultStr(regexParser.notcontains(value)).ltrim("/").rtrim("/"),'i')}
155
- case "EQ" :
156
- return {operator:'$eq',value}
157
- case "NEQ" :
158
- return {operator:"$ne",value}
159
- case "GT":
160
- return {operator:"$gt",value}
161
- case "GTE":
162
- return {operator:"$gte",value}
163
- case "LT":
164
- return {operator:"$lt",value}
165
- case "LTE":
166
- return {operator:"$lte",value}
167
- case "IN":
168
- return {operator:"$in",value}
169
- case "NOT IN":
170
- return {operator:"$in",value}
171
- }
172
- }
173
-
174
- let Operators = {
175
- NONE: null,
176
- MATCH: {
177
- name: 'contient',
178
- func: function(value, term) {
179
- if(value) {
180
- return value.toString().search(utils.isRegExp(term) ? term : new RegExp(term, 'i')) >= 0;
181
- } else {
182
- return !(!!term);
183
- }
184
- },
185
- regexpSupported: true
186
- },
187
- NOTMATCH: {
188
- name: 'ne contient pas',
189
- func: function(value, term) {
190
- if(value) {
191
- return value.toString().search(utils.isRegExp(term) ? term : new RegExp(term, 'i')) < 0;
192
- } else {
193
- return !!term;
194
- }
195
- },
196
- regexpSupported: true
197
- },
198
- EQ: {
199
- name: '=',
200
- func: function(value, term) {
201
- return value == term;
202
- },
203
- regexpSupported: false
204
- },
205
- NEQ: {
206
- name: '<>',
207
- func: function(value, term) {
208
- return value != term;
209
- },
210
- regexpSupported: false
211
- },
212
- GT: {
213
- name: '>',
214
- func: function(value, term) {
215
- return value > term;
216
- },
217
- regexpSupported: false
218
- },
219
- GTE: {
220
- name: '>=',
221
- func: function(value, term) {
222
- return value >= term;
223
- },
224
- regexpSupported: false
225
- },
226
- LT: {
227
- name: '<',
228
- func: function(value, term) {
229
- return value < term;
230
- },
231
- regexpSupported: false
232
- },
233
- LTE: {
234
- name: '<=',
235
- func: function(value, term) {
236
- return value <= term;
237
- },
238
- regexpSupported: false
239
- }
240
- };
241
- const utils = {
242
- ALL: '#All#',
243
- NONE: '#None#',
244
- BLANK: '#Blank#"',
245
- expressionFilter : function(operator, term, staticValue, excludeStatic) {
246
- var self = this;
247
-
248
- this.operator = Operators.get(operator);
249
- this.regexpMode = false;
250
- this.term = term || null;
251
- if(this.term && this.operator && this.operator.regexpSupported) {
252
- if(utils.isRegExp(this.term)) {
253
- this.regexpMode = true;
254
- if(!this.term.ignoreCase) {
255
- this.term = new RegExp(this.term.source, 'i');
256
- }
257
- }
258
- }
259
-
260
- this.staticValue = staticValue;
261
- this.excludeStatic = excludeStatic;
262
-
263
- this.test = function(value) {
264
- if(Array.isArray(self.staticValue)) {
265
- var found = self.staticValue.indexOf(value) >= 0;
266
- return (self.excludeStatic && !found) || (!self.excludeStatic && found);
267
- } else if(self.term) {
268
- return self.operator.func(value, self.term);
269
- } else if(self.staticValue === true || self.staticValue === utils.ALL) {
270
- return true;
271
- } else if(self.staticValue === false || self.staticValue === utils.NONE) {
272
- return false;
273
- } else {
274
- return true;
275
- }
276
- };
277
-
278
- this.isAlwaysTrue = function() {
279
- return !(self.term || Array.isArray(self.staticValue) || self.staticValue === utils.NONE || self.staticValue === false);
280
- };
281
- },
282
- defaultOperator : 'MATCH',
283
- Operators,
284
- constants : {},
285
- items : {
286
- EQ: Operators.EQ.name,
287
- MATCH : Operators.MATCH.name,
288
- NOTMATCH : Operators.NOTMATCH.name,
289
- NEQ : Operators.NEQ.name,
290
- GT : Operators.GT.name,
291
- GTE : Operators.GTE.name,
292
- LT : Operators.LT.name,
293
- LTE : Operators.LTE.name
294
- },
295
- isRegExp: function(obj) {
296
- return Object.prototype.toString.apply(obj) === '[object RegExp]';
297
- },
298
- /**
299
- * Escapes all RegExp special characters.
300
- */
301
- escapeRegex: function(re) {
302
- return re.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
303
- },
304
- /**** vérifie si la valeur {value}, match la valeur {filterText}
305
- * @param {object : {
306
- * value : la valeur à vérifier
307
- * filterText : le texte à vérifier si value le match
308
- * operateur : chaine de caractère dans la liste des opérateurs :, props Operators, ci-desous
309
- * useRegex : Spécifie si l'expression régulière sera utilisée pour la recherche
310
- * }}
311
- */
312
- match : ({value,filterText,operator,useRegex})=>{
313
- if(isNonNullString(operator)){
314
- operator = Operators[operator]
315
- }
316
- filterText = defaultStr(filterText);
317
- operator = defaultObj(operator);
318
- let isSearchMode = filterText !== '';
319
- if(operator && isFunction(operator.func)){
320
- let opterm = operator.regexpSupported && isSearchMode ? (useRegex ? filterText : utils.escapeRegex(filterText)) : filterText;
321
- return !isSearchMode || operator.func(value, opterm)
322
- }
323
- return !isSearchMode ? true : defaultStr(value).toLowerCase().contains(filterText.toLowerCase());
324
- },
325
- /**
326
- * Returns the first element in the array that satisfies the given predicate
327
- * @param {Array} array the array to search
328
- * @param {function} predicate Function to apply to each element until it returns true
329
- * @return {Object} The first object in the array that satisfies the predicate or undefined.
330
- */
331
- findInArray: function(array, predicate) {
332
- if (this.isArray(array) && predicate) {
333
- for (var i = 0; i < array.length; i++) {
334
- var item = array[i];
335
- if (predicate(item)) {
336
- return item;
337
- }
338
- }
339
- }
340
- return undefined;
341
- },
342
- /**
343
- * Returns a JSON string represenation of an object
344
- * @param {object} obj
345
- * @return {string}
346
- */
347
- jsonStringify: function(obj, censorKeywords) {
348
- function censor(key, value) {
349
- return censorKeywords && censorKeywords.indexOf(key) > -1 ? undefined : value;
350
- }
351
- return JSON.stringify(obj, censor, 2);
352
- }
353
- }
354
-
355
- for(let i in utils.items){
356
- utils.constants[i] = i;
357
- }
358
-
359
- /*** prend en paramètre un objet de filtres et les prépare pour la requête distante
360
- * @param {object} filtersToPrepare les filtres à exploiter pour la requête distante
361
- * le tableau des filtres
362
- * @param {function|object} filter|options, la méthode utilisée pour effectuer un filtre sur les les élément à prendre en compte
363
- *
364
- */
365
- export const prepareFilters = (filtersToPrepare,opts)=>{
366
- if(typeof opts =='function'){
367
- opts = {filter:opts};
368
- }
369
- let {filter,convertToSQL:convToSQL} = opts;
370
- const filters = {}
371
- filter = typeof filter =='function'? filter : x=>true;
372
- Object.map(filtersToPrepare,(f,i)=>{
373
- if(!isObj(f) || !filter(f) || !isNonNullString(f.operator) || !isNonNullString(f.action)) {
374
- return;
375
- }
376
- f.field = defaultStr(f.field,i).trim();
377
- f.action = defaultStr(f.action).toLowerCase().trim();
378
- if(f.action =="$today"){
379
- f.operator = "$and";
380
- f.action = "$eq"
381
- }
382
- filters[f.operator] = defaultArray(filters[f.operator]);
383
- const ob = {};
384
- ob[f.field] = {}
385
- if(f.action == "$period"){
386
- let sp = defaultStr(f.value);
387
- if(sp){
388
- sp = sp.split("=>");
389
- const isValid1 = DateLib.isValidSQLDate(sp[0]) || DateLib.isValidSQLDateTime(sp[0]);
390
- const isValid2 = DateLib.isValidSQLDate(sp[1]) || DateLib.isValidSQLDateTime(sp[1]);
391
- if(isValid1 && isValid2){
392
- filters[f.operator].push({
393
- [f.field] : {$gte:sp[0]}
394
- })
395
- filters[f.operator].push({
396
- [f.field] : {$lte:sp[1]}
397
- })
398
- }
399
- }
400
- } else {
401
- ob[f.field][f.action] = f.value;
402
- filters[f.operator].push(ob)
403
- }
404
- });
405
- return convToSQL ? convertToSQL(filters) : filters;
406
- }
407
-
408
- /*** la liste des actions supportés par les filtres
409
- * @see : https://github.com/cloudant/mango from mango query mapping
410
- *
411
- */
412
- export const actions = ["$lt", "$gt", "$lte", "$gte", "$eq", "$exists", "$type", "$in", "$nin", "$all", "$size", "$or", "$nor", "$not", "$mod", "$regex", "$elemMatch"]
413
-
414
- export default utils;
415
-
416
- /*** convertis les filtres pris au format mangoesQuey, au format de sortie SQL
417
- * @see : https://github.com/gordonBusyman/mongo-to-sql-converter
418
- * @param {object} filters, les filtres au format mango query à convertir au format SQL
419
- */
420
- export const convertToSQL = (filters)=>{
421
- if(!isObjOrArray(filters)) return [];
422
- const whereParsed = mangoParser.parse(filters)
423
- return whereParsed.parts.reduce((prev, curr) => {
424
- const c = whereClauseToSQL(curr);
425
- return c ? [...prev,c] : prev;
426
- }, []).map((filter)=>{
427
- if(filter.field === MANGO_QUERY_OPERATOR){
428
- delete filter.field;
429
- }
430
- return filter;
431
- });
432
- }
433
- export const MANGO_QUERY_OPERATOR = "MANGO_QUERY_OPERATOR";
434
- const whereClauseToSQL = (currentMongoParserElement) => {
435
- let { field, operator, operand } = currentMongoParserElement;
436
- if(!isNonNullString(operator) || !operatorsMap[operator]) return null;
437
- operator = operatorsMap[operator]
438
- if(operator == 'LIKE'){
439
- const deparsed = regexDeparser(operand);
440
- if(!isObj(deparsed)){
441
- return null;
442
- }
443
- operand = deparsed.value;
444
- const deparsedOp = deparsed.operator;
445
- if(deparsedOp =='notcontains'){
446
- operator = "NOT LIKE";
447
- }
448
- if(deparsedOp =='equals'){
449
- operator = operatorsMap.$eq;
450
- } else if(deparsedOp =='notequals'){
451
- operator = operatorsMap.$ne;
452
- } else{
453
- const opMap = regexExpressions[deparsedOp];
454
- if(!opMap || typeof opMap.sql !=='function') return null;
455
- operand = opMap.sql(operand);
456
- }
457
- }
458
- // AND or OR operators with nested elements
459
- if (typeof field === 'undefined') {
460
- // parse nested elements
461
- const nested = operand.reduce((prev, curr) => {
462
- const parsed = mangoParser.parse(curr);
463
- const prepared = whereClauseToSQL(parsed.parts[0]);
464
- if(prepared){
465
- return [...prev,prepared]
466
- }
467
- return prev;
468
- }, [])
469
-
470
- // nested WHERE element
471
- return {
472
- field: MANGO_QUERY_OPERATOR,
473
- operator,
474
- operand: nested
475
- }
476
- }
477
- // simple WHERE element
478
- return {
479
- field,
480
- operator,
481
- operand
482
- }
483
- }
484
-
485
- // map mongoDB -> SQL operators
486
- const operatorsMap = {
487
- $or: 'OR',
488
- $and: 'AND',
489
- $lt: '<',
490
- $lte: '<=',
491
- $gt: '>',
492
- $gte: '>=',
493
- $ne: '!=',
494
- $in: 'IN',
495
- $nin : 'NOT IN',
496
- $eq: '=',
497
- $regex : "LIKE"
498
- }
499
-
500
- /**
501
- *
502
- * @param {*} operand
503
- * @param {*} operator
504
- * @param {*} field
505
- *
506
- * Return the operand in right format
507
- */
508
- export const getTyppedOperand = (operand, operator, field) => {
509
- if (typeof operand === 'string') { // wrap strings in double quots
510
- return "'" +(operand) + "'"
511
- } else if (operator === 'IN' || operator =='NOT IN') { // wrap IN arguments in brackers
512
- operand = Array.isArray(operand)? operand.map(op => getTyppedOperand(op, null, null))
513
- .join(', '): operand;
514
- return '(' + operand + ')'
515
- } else if (!isNonNullString(field) && Array.isArray(operand)) { // AND or OR elements
516
- // recursively call 'buildWhereElement' for nested elements
517
- // join each element with operator AND or OR
518
- return operand.reduce((prev, curr) => {
519
- return [...prev, buildWhereElement(curr)]
520
- }, []).join(' ' + operator + ' ')
521
- } else {
522
- return operand
523
- }
524
- }
525
-
526
- /**
527
- *
528
- * @param {*} elem
529
- *
530
- * Return element of WHERE clause
531
- */
532
- export const buildWhereElement = (elem) => {
533
- const { field, operator, operand } = elem
534
- if (!isNonNullString(field)) { // nested WHERE element
535
- return '(' + getTyppedOperand(operand, operator, field) + ')'
536
- } else { // simple WHERE element
537
- return field + ' ' + operator + ' ' + getTyppedOperand(operand, operator, field)
538
- }
539
- }
540
-
541
- /**** construit une requête Where à partir des filtres préparé dans le tableau whereClausePrepared
542
- * @see : https://github.com/gordonBusyman/mongo-to-sql-converter
543
- * @parm {array} whereClausePrepared, les filtres préparés avec la méthode prepareFilters puis convertis avec la fonction convertToSQL
544
- @return {string}, la requête Where correspondante
545
- */
546
- export const buildWhere = (whereClausePrepared)=>{
547
- if(!Array.isArray(whereClausePrepared)) return null;
548
- // build WHERE string clause by adding each element of array to it, separated with AND
549
- return whereClausePrepared.reduce((prev, curr) => [
550
- ...prev, buildWhereElement(curr)
551
- ], []).join(' AND ');
552
- }