@fto-consult/expo-ui 2.34.0 → 2.34.2
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/appConfig.txt +2 -1
- package/package.json +2 -2
- package/src/App.js +31 -9
- package/src/components/Datagrid/Accordion/index.js +5 -5
- package/src/components/Datagrid/Common/Common.js +62 -48
- package/src/components/Datagrid/SWRDatagrid.js +20 -8
- package/src/components/Form/Fields/SelectTableData/Component.js +23 -12
- package/src/components/Form/FormData/componentsTypes.js +1 -0
- package/src/components/ScrollView/index.js +6 -1
package/appConfig.txt
CHANGED
|
@@ -15,5 +15,6 @@
|
|
|
15
15
|
sprintfSelectors : {
|
|
16
16
|
"&libele&" : selectLabel,
|
|
17
17
|
}
|
|
18
|
-
getTableData : {function(tableName)=>table} retourne l'ojet table data
|
|
18
|
+
getTableData : {function(tableName)=>table} retourne l'ojet table data,
|
|
19
|
+
swrRefreshTimeout : {number} le délai d'inactivité auquel, une fois l'application active, les données de type listData sont rafraichies
|
|
19
20
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fto-consult/expo-ui",
|
|
3
|
-
"version": "2.34.
|
|
3
|
+
"version": "2.34.2",
|
|
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": "^1.
|
|
64
|
+
"@fto-consult/common": "^2.1.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",
|
package/src/App.js
CHANGED
|
@@ -30,25 +30,37 @@ import appConfig from "$capp/config";
|
|
|
30
30
|
import {showPrompt} from "$components/Dialog/confirm";
|
|
31
31
|
import { AppState } from 'react-native'
|
|
32
32
|
import {canFetchOffline} from "$capi/utils";
|
|
33
|
+
import {defaultNumber} from "$utils";
|
|
34
|
+
import { timeout as SWR_REFRESH_TIMEOUT} from '$ecomponents/Datagrid/SWRDatagrid';
|
|
33
35
|
|
|
34
36
|
import * as Utils from "$utils";
|
|
35
37
|
Object.map(Utils,(v,i)=>{
|
|
36
38
|
if(typeof v =='function' && typeof window !='undefined' && window && !window[i]){
|
|
37
39
|
window[i] = v;
|
|
38
40
|
}
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
+
});
|
|
41
42
|
export default function getIndex(options){
|
|
42
43
|
const {App,onMount,onUnmount,preferences:appPreferences} = defaultObj(options);
|
|
43
44
|
return function MainIndexComponent() {
|
|
44
45
|
const isScreenFocusedRef = React.useRef(true);
|
|
46
|
+
///garde pour chaque écran sa date de dernière activité
|
|
47
|
+
const screensRef = React.useRef({});//la liste des écrans actifs
|
|
48
|
+
const activeScreenRef = React.useRef('');
|
|
49
|
+
const prevActiveScreenRef = React.useRef('');
|
|
50
|
+
const appStateRef = React.useRef({});
|
|
45
51
|
React.useEffect(()=>{
|
|
46
52
|
///la fonction de rappel lorsque le composant est monté
|
|
47
53
|
let cb = typeof onMount =='function'? onMount() : null;
|
|
48
|
-
const onScreenFocus = ()=>{
|
|
54
|
+
const onScreenFocus = ({sanitizedName})=>{
|
|
55
|
+
prevActiveScreenRef.current = activeScreenRef.current;
|
|
56
|
+
if(activeScreenRef.current){
|
|
57
|
+
screensRef.current[activeScreenRef.current] = null;
|
|
58
|
+
}
|
|
59
|
+
screensRef.current[sanitizedName] = new Date();
|
|
60
|
+
activeScreenRef.current = sanitizedName;
|
|
49
61
|
isScreenFocusedRef.current = true;
|
|
50
62
|
}, onScreenBlur = ()=>{
|
|
51
|
-
|
|
63
|
+
isScreenFocusedRef.current = false;
|
|
52
64
|
}
|
|
53
65
|
APP.on(APP.EVENTS.SCREEN_FOCUS,onScreenFocus);
|
|
54
66
|
APP.on(APP.EVENTS.SCREEN_BLUR,onScreenBlur);
|
|
@@ -86,18 +98,28 @@ export default function getIndex(options){
|
|
|
86
98
|
return APP.isOnline();
|
|
87
99
|
},
|
|
88
100
|
isVisible() {
|
|
89
|
-
|
|
90
|
-
return false;
|
|
91
|
-
|
|
101
|
+
const screen = activeScreenRef.current;
|
|
102
|
+
if(!screen) return false;
|
|
103
|
+
if(!screensRef.current[screen]){
|
|
104
|
+
screensRef.current[screen] = new Date();
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
const date = screensRef.current[screen];
|
|
108
|
+
const diff = new Date().getTime() - date.getTime();
|
|
109
|
+
const timeout = defaultNumber(appConfig.get("swrRefreshTimeout"),SWR_REFRESH_TIMEOUT)
|
|
110
|
+
//console.log(diff,"is diff and ",date.toFormat("HH:MM:ss"),screensRef,screen);
|
|
111
|
+
return diff >= timeout ? true : false;
|
|
92
112
|
},
|
|
93
113
|
initFocus(callback) {
|
|
94
114
|
let appState = AppState.currentState
|
|
95
115
|
const onAppStateChange = (nextAppState) => {
|
|
96
116
|
/* If it's resuming from background or inactive mode to active one */
|
|
97
|
-
|
|
117
|
+
const active = appState.match(/inactive|background/) && nextAppState === 'active';
|
|
118
|
+
if (active) {
|
|
98
119
|
callback()
|
|
99
120
|
}
|
|
100
|
-
appState = nextAppState
|
|
121
|
+
appState = nextAppState;
|
|
122
|
+
appStateRef.current = !!active;
|
|
101
123
|
}
|
|
102
124
|
// Subscribe to the app state change events
|
|
103
125
|
const subscription = AppState.addEventListener('change', onAppStateChange);
|
|
@@ -12,7 +12,6 @@ import BottomSheet from "$ecomponents/BottomSheet/Provider";
|
|
|
12
12
|
import {isMobileMedia} from "$cplatform/dimensions";
|
|
13
13
|
import {isNativeMobile} from "$cplatform";
|
|
14
14
|
import Icon,{MENU_ICON} from "$ecomponents/Icon";
|
|
15
|
-
import SimpleSelect from "$ecomponents/SimpleSelect";
|
|
16
15
|
import Dropdown from "$ecomponents/Dropdown";
|
|
17
16
|
import React from "$react";
|
|
18
17
|
import Footer from "../Footer/Footer";
|
|
@@ -21,13 +20,14 @@ import CommonTableDatagrid from "../Common/TableData";
|
|
|
21
20
|
import BackToTop from "$ecomponents/BackToTop";
|
|
22
21
|
import FiltersAccordionComponent from "./Filters";
|
|
23
22
|
import RenderType from "../RenderType";
|
|
24
|
-
import { flatMode
|
|
25
|
-
import
|
|
23
|
+
import { flatMode} from "$ecomponents/TextField";
|
|
24
|
+
import {FlashList} from "$ecomponents/List";
|
|
26
25
|
import theme,{Colors} from "$theme";
|
|
27
26
|
import {getRowStyle,styles as rStyles} from "../utils";
|
|
28
27
|
import Avatar from "$ecomponents/Avatar";
|
|
29
28
|
import {defaultObj,isOb,isNonNullString} from "$utils";
|
|
30
29
|
import PropTypes from "prop-types";
|
|
30
|
+
import {isTouchDevice} from "$platform";
|
|
31
31
|
|
|
32
32
|
const DatagridFactory = (Factory)=>{
|
|
33
33
|
Factory = Factory || CommonDatagrid;
|
|
@@ -431,7 +431,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
431
431
|
} = this.preparedColumns;
|
|
432
432
|
const hasFootersFields = this.hasFootersFields();
|
|
433
433
|
const datagridHeader = <View testID={testID+"_HeaderContainer"} pointerEvents={pointerEvents} style={[styles.datagridHeader]}>
|
|
434
|
-
<ScrollView testID={testID+"_HeaderScrollView"} horizontal contentContainerStyle={StyleSheet.flatten([styles.contentContainerStyle,styles.minW100])}>
|
|
434
|
+
<ScrollView testID={testID+"_HeaderScrollView"} horizontal showsHorizontalScrollIndicator = {!isTouchDevice()} contentContainerStyle={StyleSheet.flatten([styles.contentContainerStyle,styles.minW100])}>
|
|
435
435
|
<View testID={testID+"_HeaderContentCntainer"} style={[styles.table,styles.pullRight]}>
|
|
436
436
|
{dbSelector}
|
|
437
437
|
<View testID={testID+"_HeaderQueryLimit"} style={[styles.paginationItem]}>
|
|
@@ -568,7 +568,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
568
568
|
{!canRenderChart && showFooters ? (
|
|
569
569
|
<View testID={testID+"_FooterContainer"} pointerEvents={pointerEvents} style={[theme.styles.justifyContentCenter,theme.styles.pv1]}>
|
|
570
570
|
<View testID={testID+"_FooterContentContainer"} style={[styles.footersContainer]}>
|
|
571
|
-
<ScrollView testID={testID+"_FooterScrollView"} horizontal contentContainerStyle={[styles.contentContainerStyle]}>
|
|
571
|
+
<ScrollView testID={testID+"_FooterScrollView"} horizontal showsHorizontalScrollIndicator = {!isTouchDevice()} contentContainerStyle={[styles.contentContainerStyle]}>
|
|
572
572
|
<View testID={testID+"_FooterContent"} style={[styles.table,theme.styles.p1]}>
|
|
573
573
|
{Object.mapToArray(this.getFooterValues(),(footer,field)=>{
|
|
574
574
|
return <Footer
|
|
@@ -13,7 +13,7 @@ import Image from "$ecomponents/Image";
|
|
|
13
13
|
import Icon,{COPY_ICON} from "$ecomponents/Icon";
|
|
14
14
|
import filterUtils from "$cfilters";
|
|
15
15
|
import Hashtag from "$ecomponents/Hashtag";
|
|
16
|
-
import {sortBy,isDecimal,extendObj,isObjOrArray,isObj,defaultNumber,defaultStr,isFunction,defaultBool,defaultArray,defaultObj,isNonNullString,defaultDecimal} from "$utils";
|
|
16
|
+
import {sortBy,isDecimal,defaultVal,extendObj,isObjOrArray,isObj,defaultNumber,defaultStr,isFunction,defaultBool,defaultArray,defaultObj,isNonNullString,defaultDecimal} from "$utils";
|
|
17
17
|
import {Datagrid as DatagridContentLoader} from "$ecomponents/ContentLoader";
|
|
18
18
|
import React from "$react";
|
|
19
19
|
import DateLib from "$lib/date";
|
|
@@ -1063,7 +1063,7 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1063
1063
|
this.isUpdating = false;
|
|
1064
1064
|
this.setSessionData({showFilters});
|
|
1065
1065
|
})
|
|
1066
|
-
|
|
1066
|
+
},100);
|
|
1067
1067
|
}
|
|
1068
1068
|
showFilters(){
|
|
1069
1069
|
return this.toggleFilters(true);
|
|
@@ -1096,7 +1096,7 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1096
1096
|
this.isUpdating = false;
|
|
1097
1097
|
this.setSessionData({showFooters:showOrHide})
|
|
1098
1098
|
})
|
|
1099
|
-
},
|
|
1099
|
+
},0)
|
|
1100
1100
|
}
|
|
1101
1101
|
showFooters(){
|
|
1102
1102
|
return this.toggleFooters(true);
|
|
@@ -1143,8 +1143,11 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1143
1143
|
if(isObj(footers[field])){
|
|
1144
1144
|
footers[field].visible = columns[field].visible;
|
|
1145
1145
|
}
|
|
1146
|
-
this.
|
|
1147
|
-
|
|
1146
|
+
this.setIsLoading(true,()=>{
|
|
1147
|
+
this.prepareColumns({columns});
|
|
1148
|
+
this.setState({columns});
|
|
1149
|
+
this.setIsLoading(false,false);
|
|
1150
|
+
})
|
|
1148
1151
|
}
|
|
1149
1152
|
/****le nombre maximum de courbes supportées */
|
|
1150
1153
|
getMaxSeriesSize(){
|
|
@@ -1236,26 +1239,24 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1236
1239
|
} else {
|
|
1237
1240
|
sectionListColumns[columnName] = {field:columnName};
|
|
1238
1241
|
}
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
this.
|
|
1242
|
-
this.
|
|
1243
|
-
this.
|
|
1244
|
-
|
|
1245
|
-
this.setSessionData("sectionListColumns",Object.keys(pSListColumns));
|
|
1246
|
-
});
|
|
1242
|
+
const {sectionListColumns:pSListColumns} = this.prepareColumns({sectionListColumns});
|
|
1243
|
+
this.setIsLoading(true,()=>{
|
|
1244
|
+
this.prepareData({data:this.INITIAL_STATE.data,sectionListColumns:pSListColumns},(state)=>{
|
|
1245
|
+
this.setState({...state,sectionListColumns:pSListColumns},()=>{
|
|
1246
|
+
this.setIsLoading(false,false);
|
|
1247
|
+
this.setSessionData("sectionListColumns",Object.keys(pSListColumns));
|
|
1247
1248
|
});
|
|
1248
|
-
}
|
|
1249
|
-
},
|
|
1249
|
+
});
|
|
1250
|
+
},true);
|
|
1250
1251
|
}
|
|
1251
1252
|
removeAllColumnsInSectionList(){
|
|
1252
1253
|
const {sectionListColumns} = this.prepareColumns({sectionListColumns:{}});
|
|
1253
1254
|
this.setIsLoading(true,()=>{
|
|
1254
1255
|
this.prepareData({data:this.INITIAL_STATE.data,sectionListColumns},(state)=>{
|
|
1255
1256
|
this.setState({...state,sectionListColumns,displayOnlySectionListHeaders:false},()=>{
|
|
1256
|
-
this.setIsLoading(false,false);
|
|
1257
1257
|
this.setSessionData("sectionListColumns",null);
|
|
1258
1258
|
this.setSessionData("displayOnlySectionListHeaders",false);
|
|
1259
|
+
this.setIsLoading(false,false);
|
|
1259
1260
|
});
|
|
1260
1261
|
});
|
|
1261
1262
|
},true);
|
|
@@ -1348,16 +1349,14 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1348
1349
|
}
|
|
1349
1350
|
toggleActiveAggregatorFunction(ag){
|
|
1350
1351
|
if(!isValidAggregator(ag) || ag.code == this.state.aggregatorFunction) return null;
|
|
1351
|
-
|
|
1352
|
-
this.
|
|
1353
|
-
this.
|
|
1354
|
-
this.
|
|
1355
|
-
|
|
1356
|
-
this.setIsLoading(false,false);
|
|
1357
|
-
})
|
|
1352
|
+
this.setIsLoading(true,()=>{
|
|
1353
|
+
this.prepareData({data:this.INITIAL_STATE.data,aggregatorFunction:ag.code},(state)=>{
|
|
1354
|
+
this.setState(state,()=>{
|
|
1355
|
+
this.setSessionData("aggregatorFunction",ag.code);
|
|
1356
|
+
this.setIsLoading(false,false);
|
|
1358
1357
|
})
|
|
1359
|
-
}
|
|
1360
|
-
},
|
|
1358
|
+
})
|
|
1359
|
+
},true);
|
|
1361
1360
|
}
|
|
1362
1361
|
renderAggregatorFunctionsMenu(){
|
|
1363
1362
|
const m = this.getAggregatorFunctionsMenuItems(false,false);
|
|
@@ -1440,12 +1439,17 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1440
1439
|
},
|
|
1441
1440
|
dataLabels : {
|
|
1442
1441
|
type : 'switch',
|
|
1443
|
-
label : "Affich les valeurs",
|
|
1442
|
+
label : "Affich les etiquettes de valeurs",
|
|
1444
1443
|
checkedTooltip : "Les étiquettes de valeurs seront affichées sur le graphe",
|
|
1445
1444
|
checkedValue : true,
|
|
1446
1445
|
uncheckedValue : false,
|
|
1447
1446
|
defaultValue : this.isDashboard()? true : false,
|
|
1448
1447
|
},
|
|
1448
|
+
abreviateValues : {
|
|
1449
|
+
type : "switch",
|
|
1450
|
+
label : "Abréger les valeurs numériques",
|
|
1451
|
+
defaultValue : true,
|
|
1452
|
+
},
|
|
1449
1453
|
showXaxis : {
|
|
1450
1454
|
type : "switch",
|
|
1451
1455
|
text : "Afficher l'axe des X",
|
|
@@ -1864,6 +1868,8 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1864
1868
|
chartProps[settingKey] = defaultObj(chartProps[settingKey]);
|
|
1865
1869
|
chartProps[settingKey][key] = config[key];
|
|
1866
1870
|
});
|
|
1871
|
+
const mappedColumns = {};
|
|
1872
|
+
const abreviateValues = defaultVal(config.abreviateValues,true);
|
|
1867
1873
|
const dataLabelFormatter = typeof chartProps.dataLabels?.formatter =="function"? chartProps.dataLabels.formatter : undefined;
|
|
1868
1874
|
const chartOptions = {
|
|
1869
1875
|
...chartProps,
|
|
@@ -1871,16 +1877,22 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1871
1877
|
formatter : (value, { seriesIndex, dataPointIndex, w })=> {
|
|
1872
1878
|
const serie = w.config.series[seriesIndex];
|
|
1873
1879
|
const serieName = serie.name;
|
|
1874
|
-
const column = isDonut ? defaultObj((this.state.columns[yAxisColumn.field],yAxisColumn)): defaultObj(this.chartSeriesNamesColumnsMapping[serieName]);
|
|
1880
|
+
const column = mappedColumns[seriesIndex] || isDonut ? defaultObj((this.state.columns[yAxisColumn.field],yAxisColumn)): defaultObj(this.chartSeriesNamesColumnsMapping[serieName]);
|
|
1881
|
+
if((column) && column.field){
|
|
1882
|
+
mappedColumns[seriesIndex] = column;
|
|
1883
|
+
}
|
|
1884
|
+
/*if(value>=660 && value < 661){
|
|
1885
|
+
console.log(value," will format ",column,seriesIndex,serieName)
|
|
1886
|
+
}*/
|
|
1875
1887
|
const columnField = defaultStr(column.field, isDonut? config.y : undefined);
|
|
1876
1888
|
if(dataLabelFormatter){
|
|
1877
1889
|
return dataLabelFormatter({value,column,columnDef:column,columnField,serie,serieName,seriesIndex})
|
|
1878
1890
|
}
|
|
1879
1891
|
if(typeof value !=='number') return value;
|
|
1880
1892
|
if(defaultStr(column.format).toLowerCase() ==='money'){
|
|
1881
|
-
return value.formatMoney();
|
|
1893
|
+
return abreviateValues ? value.abreviate2FormatMoney() : value.formatMoney();
|
|
1882
1894
|
}
|
|
1883
|
-
return value.formatNumber();
|
|
1895
|
+
return abreviateValues ? value.abreviate() : value.formatNumber();
|
|
1884
1896
|
}
|
|
1885
1897
|
}),
|
|
1886
1898
|
title :extendObj(true,{}, {
|
|
@@ -1940,13 +1952,10 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1940
1952
|
}
|
|
1941
1953
|
yLabels.formatter = (value)=>{
|
|
1942
1954
|
if(typeof value !='number') return value;
|
|
1943
|
-
if(yLabelFormat =='money' || (isDonut && yAxisColumn.format =="money")){
|
|
1944
|
-
return value.formatMoney();
|
|
1945
|
-
}
|
|
1946
|
-
if(yLabelsColumn && yLabelsColumn.format =='money'){
|
|
1947
|
-
return value.formatMoney();
|
|
1955
|
+
if((yLabelFormat =='money' || (isDonut && yAxisColumn.format =="money")) || (yLabelsColumn && yLabelsColumn.format =='money')){
|
|
1956
|
+
return abreviateValues ? value.abreviate2FormatMoney() : value.formatMoney();
|
|
1948
1957
|
}
|
|
1949
|
-
return value.formatNumber();
|
|
1958
|
+
return abreviateValues? value.abreviate() : value.formatNumber();
|
|
1950
1959
|
}
|
|
1951
1960
|
chartOptions.chart.id = this.chartIdPrefix+"-"+defaultStr(chartType.key,"no-key");
|
|
1952
1961
|
if(!chartType.isDonut){
|
|
@@ -1991,8 +2000,11 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1991
2000
|
const displayOnlySectionListHeaders = !!!this.state.displayOnlySectionListHeaders;
|
|
1992
2001
|
this.setSessionData("displayOnlySectionListHeaders",displayOnlySectionListHeaders);
|
|
1993
2002
|
if(!displayOnlySectionListHeaders){
|
|
1994
|
-
return this.
|
|
1995
|
-
this.
|
|
2003
|
+
return this.setIsLoading(true,()=>{
|
|
2004
|
+
this.prepareData({data:this.INITIAL_STATE.data,displayOnlySectionListHeaders},(state)=>{
|
|
2005
|
+
this.setState({...state,showFooters});
|
|
2006
|
+
this.setIsLoading(false,false);
|
|
2007
|
+
})
|
|
1996
2008
|
})
|
|
1997
2009
|
} else {
|
|
1998
2010
|
this.setIsLoading(true,()=>{
|
|
@@ -2003,11 +2015,11 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
2003
2015
|
}
|
|
2004
2016
|
});
|
|
2005
2017
|
this.setState({data,displayOnlySectionListHeaders,showFooters},()=>{
|
|
2006
|
-
this.setIsLoading(false
|
|
2018
|
+
this.setIsLoading(false,false);
|
|
2007
2019
|
});
|
|
2008
2020
|
},true)
|
|
2009
2021
|
}
|
|
2010
|
-
},
|
|
2022
|
+
},0);
|
|
2011
2023
|
}
|
|
2012
2024
|
/*** permet d'effectuer le rendu des colonnes groupable dans le menu item */
|
|
2013
2025
|
renderSectionListMenu(){
|
|
@@ -2892,15 +2904,17 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
2892
2904
|
if(typeof enablePointerEvents =='boolean'){
|
|
2893
2905
|
this.enablePointerEventsRef.current = enablePointerEvents;
|
|
2894
2906
|
}
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
cb
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
cb
|
|
2903
|
-
|
|
2907
|
+
setTimeout(()=>{
|
|
2908
|
+
if(this.canSetIsLoading() && typeof loading =='boolean'){
|
|
2909
|
+
return this.progressBarRef.current.setIsLoading(loading,()=>{
|
|
2910
|
+
if(typeof cb =='function'){
|
|
2911
|
+
cb();
|
|
2912
|
+
}
|
|
2913
|
+
});
|
|
2914
|
+
} else if(typeof cb =='function'){
|
|
2915
|
+
cb();
|
|
2916
|
+
}
|
|
2917
|
+
},loading === false && enablePointerEvents === false ? 0 : 0);
|
|
2904
2918
|
return false;
|
|
2905
2919
|
}
|
|
2906
2920
|
/**** met à jour l'état de progression de la mise à jour du tableau */
|
|
@@ -49,14 +49,26 @@ export const setSessionData = (key,value)=>{
|
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
const timeout = 5000*60
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
52
|
+
export const timeout = 5000*60//*60;
|
|
53
|
+
/***@see : https://swr.vercel.app/docs/api */
|
|
54
|
+
|
|
55
|
+
export const getSWROptions = ()=>{
|
|
56
|
+
const delay = defaultNumber(appConfig.get("swrRefreshTimeout"),timeout);
|
|
57
|
+
return {
|
|
58
|
+
dedupingInterval : delay,
|
|
59
|
+
errorRetryInterval : delay*2,
|
|
60
|
+
errorRetryCount : 5,
|
|
61
|
+
revalidateOnMount : false,//enable or disable automatic revalidation when component is mounted
|
|
62
|
+
revalidateOnFocus : true, //automatically revalidate when window gets focused (details)
|
|
63
|
+
revalidateOnReconnect : true, //automatically revalidate when the browser regains a network
|
|
64
|
+
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
|
|
65
|
+
refreshWhenHidden : false, //polling when the window is invisible (if refreshInterval is enabled)
|
|
66
|
+
refreshWhenOffline : false, //polling when the browser is offline (determined by navigator.onLine)
|
|
67
|
+
shouldRetryOnError : false, //retry when fetcher has an error
|
|
68
|
+
dedupingInterval : delay,//dedupe requests with the same key in this time span in milliseconds
|
|
69
|
+
}
|
|
59
70
|
}
|
|
71
|
+
|
|
60
72
|
const getDefaultPaginationRowsPerPageItems = ()=>{
|
|
61
73
|
return [5,10,15,20,25,30,40,50,60,80,100,500,1000,...(isDesktopMedia() ? [1500,2000,2500,3000,3500,4000,4500,5000,10000]:[])];
|
|
62
74
|
}
|
|
@@ -203,7 +215,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
|
203
215
|
},
|
|
204
216
|
showError : false,
|
|
205
217
|
swrOptions : {
|
|
206
|
-
...
|
|
218
|
+
...getSWROptions(),
|
|
207
219
|
...defaultObj(appConfig.swr),
|
|
208
220
|
},
|
|
209
221
|
});
|
|
@@ -20,28 +20,36 @@ import appConfig from "$appConfig";
|
|
|
20
20
|
* foreignKeyLabel : Le libélé dans la table étrangère
|
|
21
21
|
*/
|
|
22
22
|
const TableDataSelectField = React.forwardRef((_props,ref)=>{
|
|
23
|
-
let {foreignKeyColumn,foreignKeyTable,foreignKeyLabel,dropdownActions,fields,fetchItems:customFetchItem,convertFiltersToSQL,mutateFetchedItems,getForeignKeyTable,onFetchItems,isFilter,isUpdate,isDocEditing,items,onAddProps,fetchDataOpts,...props} = _props;
|
|
23
|
+
let {foreignKeyColumn,foreignKeyTable,fetchItemsPath,foreignKeyLabel,dropdownActions,fields,fetchItems:customFetchItem,convertFiltersToSQL,mutateFetchedItems,getForeignKeyTable,onFetchItems,isFilter,isUpdate,isDocEditing,items,onAddProps,fetchDataOpts,...props} = _props;
|
|
24
24
|
props = defaultObj(props);
|
|
25
25
|
props.data = defaultObj(props.data);
|
|
26
26
|
foreignKeyColumn = foreignKeyColumn.trim();
|
|
27
27
|
convertFiltersToSQL = defaultVal(convertFiltersToSQL,willConvertFiltersToSQL());
|
|
28
28
|
getForeignKeyTable = getForeignKeyTable || appConfig.getDatabaseTableData;
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
let fKeyTable = typeof getForeignKeyTable =='function' ? getForeignKeyTable(foreignKeyTable,props) : undefined;
|
|
30
|
+
fetchItemsPath = defaultStr(fetchItemsPath).trim();
|
|
31
|
+
if(!fetchItemsPath && (!isObj(fKeyTable) || !(defaultStr(fKeyTable.tableName,fKeyTable.table)))){
|
|
31
32
|
console.error("type de données invalide pour la fKeyTable ",fKeyTable," composant SelectTableData",_props);
|
|
32
33
|
return null;
|
|
33
34
|
}
|
|
35
|
+
fKeyTable = defaultObj(fKeyTable);
|
|
34
36
|
foreignKeyTable = defaultStr(fKeyTable.tableName,fKeyTable.table,foreignKeyTable).trim().toUpperCase();
|
|
35
37
|
const isMounted = React.useIsMounted();
|
|
36
|
-
const showAdd = isFilter ? false : React.useRef(Auth.isTableDataAllowed({foreignKeyTable,action:'create'}) ? defaultVal(props.showAdd,props.showAddBtn,true) : false).current;
|
|
38
|
+
const showAdd = isFilter || !foreignKeyTable ? false : React.useRef(Auth.isTableDataAllowed({foreignKeyTable,action:'create'}) ? defaultVal(props.showAdd,props.showAddBtn,true) : false).current;
|
|
37
39
|
const [state,setState] = React.useState({
|
|
38
40
|
items : [],isLoading : true,
|
|
39
41
|
});
|
|
40
42
|
fetchDataOpts = Object.clone(defaultObj(fetchDataOpts));
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
const queryPath = fetchItemsPath || typeof fKeyTable.queryPath =='string' && fKeyTable.queryPath || typeof fKeyTable.fetchPath =='string' && fKeyTable.fetchPath || '';
|
|
44
|
+
const cFetch = typeof customFetchItem =='function' && customFetchItem;
|
|
45
|
+
const fetchItems = (opts)=>{
|
|
46
|
+
opts.showError = false;
|
|
47
|
+
if(cFetch) return cFetch(queryPath,opts);
|
|
48
|
+
if(queryPath){
|
|
49
|
+
return fetch(queryPath,opts);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
isUpdate = defaultBool(isUpdate,typeof isDocEditing ==='function' && isDocEditing({data:props.data,foreignKeyTable,foreignKeyColumn}));
|
|
45
53
|
if(isFilter){
|
|
46
54
|
isUpdate = false;
|
|
47
55
|
}
|
|
@@ -98,13 +106,16 @@ const TableDataSelectField = React.forwardRef((_props,ref)=>{
|
|
|
98
106
|
let opts = Object.clone(fetchDataOpts);
|
|
99
107
|
opts.selector = prepareFilters(fetchDataOpts.selector,{convertToSQL:convertFiltersToSQL});
|
|
100
108
|
opts = getFetchOptions(opts);
|
|
101
|
-
const r = fetchItems
|
|
109
|
+
const r = fetchItems(opts);
|
|
102
110
|
if(r === false) return;
|
|
103
111
|
if(isPromise(r)){
|
|
104
112
|
r.then((args)=>{
|
|
105
113
|
if(Array.isArray(args)){
|
|
106
114
|
args = {data : args};
|
|
107
115
|
}
|
|
116
|
+
if(!isObj(args)) {
|
|
117
|
+
args = {items:[]}
|
|
118
|
+
}
|
|
108
119
|
let items = args.items = args.data = Array.isArray(args.items) ? args.items : Array.isArray(args.data) ? args.data : [];
|
|
109
120
|
if(dat && isUpdate){
|
|
110
121
|
if(isFunction(mutateFetchedItems)){
|
|
@@ -177,7 +188,6 @@ const TableDataSelectField = React.forwardRef((_props,ref)=>{
|
|
|
177
188
|
{...props}
|
|
178
189
|
isFilter = {isFilter}
|
|
179
190
|
showAdd = {!isFilter && showAdd}
|
|
180
|
-
{...React.setProps(Dropdown,fKeyTable,{})}
|
|
181
191
|
{...state}
|
|
182
192
|
dialogProps = {dialogProps}
|
|
183
193
|
ref = {ref}
|
|
@@ -220,14 +230,15 @@ TableDataSelectField.propTypes = {
|
|
|
220
230
|
...Dropdown.propTypes,
|
|
221
231
|
mutateFetchedItems : PropTypes.func, //la fonction permettant d'effectuer une mutation sur l'ensemble des donnéees récupérées à distance
|
|
222
232
|
fetchItems : PropTypes.func,//la fonction de rappel à utiliser pour faire une requête fetch permettant de selectionner les données à distance
|
|
233
|
+
getForeignKeyTable : PropTypes.func, //la fonction permettant de récupérer la fKeyTable data dont fait référence le champ
|
|
234
|
+
foreignKeyTable : PropTypes.string, //le nom de la fKeyTable data à laquelle se reporte le champ
|
|
235
|
+
fetchItemsPath : PropTypes.string, //le chemin d'api pour récupérer les items des données étrangères en utilisant la fonction fetch
|
|
223
236
|
beforeFetchItems : PropTypes.func, //appelée immédiatement avant l'exécution de la requête fetch
|
|
224
237
|
foreignKeyColumn : PropTypes.string.isRequired,//le nom de la clé étrangère à laquelle fait référence la colone dans la fKeyTable
|
|
225
238
|
foreignKeyLabel : PropTypes.oneOfType([
|
|
226
239
|
PropTypes.string,
|
|
227
240
|
PropTypes.func, //s'il s'agit d'une fonciton qui sera appelée
|
|
228
241
|
]),
|
|
229
|
-
getForeignKeyTable : PropTypes.func, //la fonction permettant de récupérer la fKeyTable data dont fait référence le champ
|
|
230
|
-
foreignKeyTable : PropTypes.string, //le nom de la fKeyTable data à laquelle se reporte le champ
|
|
231
242
|
onFetchItems : PropTypes.func,
|
|
232
243
|
fetchDataOpts : PropTypes.shape({
|
|
233
244
|
fields : PropTypes.oneOfType([
|
|
@@ -108,6 +108,7 @@ export const getFilterComponentProps = (_props)=>{
|
|
|
108
108
|
component = componentTypes[type.replaceAll("_","")];
|
|
109
109
|
} else if(isNonNullString(props.foreignKeyColumn) && isNonNullString(props.foreignKeyTable)) {
|
|
110
110
|
component = Fields.SelectTableData;
|
|
111
|
+
props.multiple = true;
|
|
111
112
|
}else {
|
|
112
113
|
const tt = type.replaceAll("_","").toLowerCase();
|
|
113
114
|
if(React.isComponent(componentTypes[tt])){
|
|
@@ -4,6 +4,7 @@ import { ScrollView,Dimensions,useWindowDimensions } from 'react-native';
|
|
|
4
4
|
import PropTypes from "prop-types";
|
|
5
5
|
import View from "$ecomponents/View";
|
|
6
6
|
import {isMobileNative,isTouchDevice} from "$cplatform";
|
|
7
|
+
import {isDesktopMedia} from "$cdimensions";
|
|
7
8
|
import {defaultStr,defaultObj} from "$utils";
|
|
8
9
|
const isNative = isMobileNative();
|
|
9
10
|
import APP from "$capp/instance";
|
|
@@ -25,7 +26,10 @@ const ScrollViewComponent = React.forwardRef((props,ref) => {
|
|
|
25
26
|
APP.off(APP.EVENTS.RESIZE_PAGE,onResizePage);
|
|
26
27
|
}
|
|
27
28
|
},[])
|
|
29
|
+
const showIndicator = !isTouchDevice() || isDesktopMedia();
|
|
28
30
|
return virtualized ? <FlatList
|
|
31
|
+
showsHorizontalScrollIndicator = {showIndicator}
|
|
32
|
+
showsVerticalScrollIndicator={showIndicator}
|
|
29
33
|
{...rest}
|
|
30
34
|
ref = {ref}
|
|
31
35
|
testID = {testID}
|
|
@@ -36,7 +40,8 @@ const ScrollViewComponent = React.forwardRef((props,ref) => {
|
|
|
36
40
|
contentContainerStyle = {[!isNative && {flex:1,flexGrow: 1,maxHeight:Math.max(height-100,250)},rest.contentContainerStyle]}
|
|
37
41
|
ListHeaderComponent={() => <View testID={testID+'_FlatListContent'} {...cProps} mediaQueryUpdateNativeProps = {mediaQueryUpdateNativeProps}
|
|
38
42
|
>{children}</View>}
|
|
39
|
-
/> : <ScrollView
|
|
43
|
+
/> : <ScrollView showsHorizontalScrollIndicator = {showIndicator}
|
|
44
|
+
showsVerticalScrollIndicator={showIndicator} ref={ref} {...rest} testID={testID} children={children}/>
|
|
40
45
|
});
|
|
41
46
|
|
|
42
47
|
ScrollViewComponent.displayName = "ScrollViewComponent";
|