@fto-consult/expo-ui 2.9.6 → 2.10.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 +2 -2
- package/src/App.js +82 -32
- package/src/components/Datagrid/Accordion/index.js +1 -1
- package/src/components/Datagrid/Common/Common.js +120 -23
- package/src/components/Datagrid/Common/ProgressBar.js +58 -0
- package/src/components/Datagrid/Common/TableData.js +15 -70
- package/src/components/Datagrid/IndexComponent.js +45 -0
- package/src/components/Datagrid/RenderTypes/index.web.js +5 -2
- package/src/components/Datagrid/Table/index.js +11 -12
- package/src/components/Datagrid/index.js +4 -40
- package/src/components/Menu/Item.js +2 -1
- package/src/layouts/Fab/index.js +0 -1
- package/src/components/Datagrid/Table/Datatable.js +0 -232
- package/src/components/Datagrid/Table/renderTable.js +0 -664
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fto-consult/expo-ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.10.1",
|
|
4
4
|
"description": "Bibliothèque de composants UI Expo,react-native",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"@expo/metro-config": "^0.4.0",
|
|
66
66
|
"@expo/vector-icons": "^13.0.0",
|
|
67
67
|
"@expo/webpack-config": "^0.17.2",
|
|
68
|
-
"@fto-consult/common": "^1.
|
|
68
|
+
"@fto-consult/common": "^1.19.1",
|
|
69
69
|
"@fto-consult/expo-ui": "^2.9.2",
|
|
70
70
|
"@gorhom/portal": "^1.0.14",
|
|
71
71
|
"@react-native-async-storage/async-storage": "~1.17.3",
|
package/src/App.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import '$session';
|
|
2
2
|
import React from 'react';
|
|
3
|
+
import {SWRConfig} from "$swr";
|
|
3
4
|
import {defaultObj} from "$utils";
|
|
4
5
|
import {updateTheme,defaultTheme} from "$theme";
|
|
5
6
|
import {Provider as PaperProvider } from 'react-native-paper';
|
|
@@ -27,6 +28,8 @@ import {isMobileNative} from "$cplatform";
|
|
|
27
28
|
import {setDeviceIdRef} from "$capp";
|
|
28
29
|
import appConfig from "$capp/config";
|
|
29
30
|
import {showPrompt} from "$components/Dialog/confirm";
|
|
31
|
+
import { AppState } from 'react-native'
|
|
32
|
+
import {canFetchOffline} from "$capi/utils";
|
|
30
33
|
|
|
31
34
|
import * as Utils from "$utils";
|
|
32
35
|
Object.map(Utils,(v,i)=>{
|
|
@@ -38,10 +41,20 @@ Object.map(Utils,(v,i)=>{
|
|
|
38
41
|
export default function getIndex(options){
|
|
39
42
|
const {App,onMount,onUnmount,preferences:appPreferences} = defaultObj(options);
|
|
40
43
|
return function MainIndexComponent() {
|
|
44
|
+
const isScreenFocusedRef = React.useRef(true);
|
|
41
45
|
React.useEffect(()=>{
|
|
42
46
|
///la fonction de rappel lorsque le composant est monté
|
|
43
47
|
let cb = typeof onMount =='function'? onMount() : null;
|
|
48
|
+
const onScreenFocus = ()=>{
|
|
49
|
+
isScreenFocusedRef.current = true;
|
|
50
|
+
}, onScreenBlur = ()=>{
|
|
51
|
+
isScreenFocusedRef.current = false;
|
|
52
|
+
}
|
|
53
|
+
APP.on(APP.EVENTS.SCREEN_FOCUS,onScreenFocus);
|
|
54
|
+
APP.on(APP.EVENTS.SCREEN_BLUR,onScreenBlur);
|
|
44
55
|
return ()=>{
|
|
56
|
+
APP.off(APP.EVENTS.SCREEN_FOCUS,onScreenFocus);
|
|
57
|
+
APP.off(APP.EVENTS.SCREEN_BLUR,onScreenBlur);
|
|
45
58
|
if(typeof onUnmount =='function'){
|
|
46
59
|
onUnmount();
|
|
47
60
|
}
|
|
@@ -64,38 +77,75 @@ export default function getIndex(options){
|
|
|
64
77
|
const child = <Index theme={theme}/>;
|
|
65
78
|
const children = typeof App =='function'? App({children:child,APP}) : child;
|
|
66
79
|
return (
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
80
|
+
<SWRConfig
|
|
81
|
+
value={{
|
|
82
|
+
provider: () => new Map(),
|
|
83
|
+
isOnline() {
|
|
84
|
+
/* Customize the network state detector */
|
|
85
|
+
if(canFetchOffline) return true;
|
|
86
|
+
return APP.isOnline();
|
|
87
|
+
},
|
|
88
|
+
isVisible() {
|
|
89
|
+
/* Customize the visibility state detector */
|
|
90
|
+
return isScreenFocusedRef.current;
|
|
91
|
+
},
|
|
92
|
+
initFocus(callback) {
|
|
93
|
+
let appState = AppState.currentState
|
|
94
|
+
const onAppStateChange = (nextAppState) => {
|
|
95
|
+
/* If it's resuming from background or inactive mode to active one */
|
|
96
|
+
if (appState.match(/inactive|background/) && nextAppState === 'active') {
|
|
97
|
+
callback()
|
|
98
|
+
}
|
|
99
|
+
appState = nextAppState
|
|
100
|
+
}
|
|
101
|
+
// Subscribe to the app state change events
|
|
102
|
+
const subscription = AppState.addEventListener('change', onAppStateChange);
|
|
103
|
+
return () => {
|
|
104
|
+
subscription?.remove()
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
initReconnect(callback) {
|
|
108
|
+
/* Register the listener with your state provider */
|
|
109
|
+
APP.on(APP.EVENTS.GO_ONLINE,callback);
|
|
110
|
+
return ()=>{
|
|
111
|
+
APP.off(APP.EVENTS.GO_ONLINE,callback);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}}
|
|
115
|
+
>
|
|
116
|
+
<GestureHandlerRootView style={{ flex: 1 }}>
|
|
117
|
+
<PaperProvider
|
|
118
|
+
theme={theme}
|
|
119
|
+
settings={{
|
|
120
|
+
icon: (props) => {
|
|
121
|
+
return <FontIcon {...props}/>
|
|
122
|
+
},
|
|
123
|
+
}}
|
|
124
|
+
>
|
|
125
|
+
<SafeAreaProvider>
|
|
126
|
+
<AuthProvider>
|
|
127
|
+
<PortalProvider>
|
|
128
|
+
<Portal.Host>
|
|
129
|
+
<ErrorBoundary>
|
|
130
|
+
<StatusBar/>
|
|
131
|
+
<PreferencesContext.Provider value={preferences}>
|
|
132
|
+
<DropdownAlert ref={notificationRef}/>
|
|
133
|
+
<PreloaderProvider/>
|
|
134
|
+
<DialogProvider responsive/>
|
|
135
|
+
<AlertProvider SimpleSelect={SimpleSelect}/>
|
|
136
|
+
<FormDataDialogProvider/>
|
|
137
|
+
{children}
|
|
138
|
+
<ErrorBoundaryProvider/>
|
|
139
|
+
<BottomSheetProvider/>
|
|
140
|
+
</PreferencesContext.Provider>
|
|
141
|
+
</ErrorBoundary>
|
|
142
|
+
</Portal.Host>
|
|
143
|
+
</PortalProvider>
|
|
144
|
+
</AuthProvider>
|
|
145
|
+
</SafeAreaProvider>
|
|
146
|
+
</PaperProvider>
|
|
147
|
+
</GestureHandlerRootView>
|
|
148
|
+
</SWRConfig>
|
|
99
149
|
);
|
|
100
150
|
}
|
|
101
151
|
};
|
|
@@ -413,7 +413,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
413
413
|
const containerHeight = winheight - y;
|
|
414
414
|
this.renderedListHeight = Math.max(300,containerHeight - (this.hasScrollViewParent() ? 50:0));
|
|
415
415
|
const isLoading = this.isLoading();
|
|
416
|
-
const _progressBar = this.getProgressBar(
|
|
416
|
+
const _progressBar = this.getProgressBar();
|
|
417
417
|
const pointerEvents = isLoading || _progressBar ? "none":"auto";
|
|
418
418
|
|
|
419
419
|
const {
|
|
@@ -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,defaultNumber,defaultStr,isFunction,defaultBool,defaultArray,defaultObj,isNonNullString,defaultDecimal} from "$utils";
|
|
16
|
+
import {sortBy,isDecimal,extendObj,isObjOrArray,isOb,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";
|
|
@@ -31,7 +31,8 @@ import copyToClipboard from "$capp/clipboard";
|
|
|
31
31
|
import { Pressable } from "react-native";
|
|
32
32
|
import TableLink from "$TableLink";
|
|
33
33
|
import appConfig from "$capp/config";
|
|
34
|
-
import stableHash from "stable-hash"
|
|
34
|
+
import stableHash from "stable-hash";
|
|
35
|
+
import DatagridProgressBar from "./ProgressBar";
|
|
35
36
|
|
|
36
37
|
export const arrayValueSeparator = ", ";
|
|
37
38
|
|
|
@@ -96,9 +97,16 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
96
97
|
[footerFieldName] : {
|
|
97
98
|
value : uniqid(footerFieldName),override:false, writable: false
|
|
98
99
|
},
|
|
100
|
+
progressBarRef : {
|
|
101
|
+
value : {current : null}
|
|
102
|
+
},
|
|
103
|
+
isLoadingRef : {
|
|
104
|
+
value : {current:false}
|
|
105
|
+
},
|
|
99
106
|
currentFilteringColumns : {value:{}}
|
|
100
107
|
})
|
|
101
|
-
|
|
108
|
+
this.isLoading = this.isLoading.bind(this);
|
|
109
|
+
this.getProgressBar = this.getProgressBar.bind(this);
|
|
102
110
|
this.state.sort.dir = defaultStr(this.state.sort.dir,this.state.sort.column == "date"?"desc":'asc')
|
|
103
111
|
this.hasColumnsHalreadyInitialized = false;
|
|
104
112
|
this.initColumns(props.columns);
|
|
@@ -142,6 +150,39 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
142
150
|
windowHeight,
|
|
143
151
|
}
|
|
144
152
|
this.selectableColumnRef = React.createRef(null);
|
|
153
|
+
let isPv = this.isPivotDatagrid();
|
|
154
|
+
if(isPv){
|
|
155
|
+
isPv = this.props.dataSourceSelector !== false;
|
|
156
|
+
} else isPv = this.props.dataSourceSelector === true ? true : false;
|
|
157
|
+
if(isPv){
|
|
158
|
+
let dataSourceSelectorProps = defaultObj(this.props.dataSourceSelectorProps);
|
|
159
|
+
['table','tableName'].map((tb,idx)=>{
|
|
160
|
+
dataSourceSelectorProps[tb] = defaultStr(this.props[tb],dataSourceSelectorProps[tb]);
|
|
161
|
+
});
|
|
162
|
+
let cDB = []//DBSelector.getDefaultSelected(dataSourceSelectorProps,this.currentDataSources,this.props);
|
|
163
|
+
let sDB = this.getSessionData().selectedDataSources;
|
|
164
|
+
cDB = Object.toArray(cDB);
|
|
165
|
+
if(cDB.length){
|
|
166
|
+
this.currentDataSources = cDB
|
|
167
|
+
} else {
|
|
168
|
+
this.currentDataSources = sDB;
|
|
169
|
+
}
|
|
170
|
+
this.setSessionData({selectedDataSources:this.currentDataSources});
|
|
171
|
+
} else {
|
|
172
|
+
this.currentDataSources = Object.toArray(this.currentDataSources);
|
|
173
|
+
}
|
|
174
|
+
if(isPv){
|
|
175
|
+
isPv = this.props.dataSourceSelector !== false;
|
|
176
|
+
} else isPv = this.props.dataSourceSelector === true ? true : false;
|
|
177
|
+
if(isPv){
|
|
178
|
+
let dataSourceSelectorProps = defaultObj(this.props.dataSourceSelectorProps);
|
|
179
|
+
['table','tableName'].map((tb)=>{
|
|
180
|
+
dataSourceSelectorProps[tb] = defaultStr(this.props[tb],this[tb],dataSourceSelectorProps[tb]);
|
|
181
|
+
});
|
|
182
|
+
this.setSessionData({selectedDataSources:this.currentDataSources});
|
|
183
|
+
} else {
|
|
184
|
+
this.currentDataSources = Object.toArray(this.currentDataSources);
|
|
185
|
+
}
|
|
145
186
|
}
|
|
146
187
|
bindResizeEvents(){
|
|
147
188
|
return false;
|
|
@@ -1082,7 +1123,7 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1082
1123
|
} else if(force){
|
|
1083
1124
|
this.setSelectedRows();
|
|
1084
1125
|
}
|
|
1085
|
-
const state = {data,
|
|
1126
|
+
const state = {data,sort : this._sort};
|
|
1086
1127
|
if((cb)){
|
|
1087
1128
|
cb(state);
|
|
1088
1129
|
}
|
|
@@ -1124,15 +1165,21 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1124
1165
|
|
|
1125
1166
|
|
|
1126
1167
|
getProgressBar(props){
|
|
1127
|
-
if(!this.isLoading() && props !== true) return null;
|
|
1128
1168
|
if(typeof props !=='object' || !props){
|
|
1129
1169
|
props = {};
|
|
1130
1170
|
}
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1171
|
+
const children = React.isValidElement(this.props.progressBar) ? this.props.progressBar :
|
|
1172
|
+
this.props.useLinesProgressBar === true || this.props.useLineProgressBar === true ? CommonDatagridComponent.LineProgressBar(props)
|
|
1173
|
+
: this.getDefaultPreloader(props);
|
|
1174
|
+
return <DatagridProgressBar
|
|
1175
|
+
{...props}
|
|
1176
|
+
onChange = {(context)=>{
|
|
1177
|
+
this.isLoadingRef.current = context.isLoading;
|
|
1178
|
+
}}
|
|
1179
|
+
isLoading = {defaultBool(this.props.isLoading,this.isLoading())}
|
|
1180
|
+
children = {children}
|
|
1181
|
+
ref = {this.progressBarRef}
|
|
1182
|
+
/>
|
|
1136
1183
|
}
|
|
1137
1184
|
handlePagination(start, limit, page) {
|
|
1138
1185
|
this._previousPagination = this._pagination;
|
|
@@ -1217,7 +1264,25 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1217
1264
|
const preparedFilters = prepareFilters(this.filters,{filter:this.canHandleFilterVal.bind(this),convertToSQL:this.willConvertFiltersToSQL()});
|
|
1218
1265
|
return preparedFilters;
|
|
1219
1266
|
}
|
|
1220
|
-
|
|
1267
|
+
onChangeDataSources(args){
|
|
1268
|
+
let {dataSources,server} = args;
|
|
1269
|
+
if(this.props.onChangeDataSources =='function' && this.props.onChangeDataSources({dataSources,prev:this.currentDataSources}) === false) return;
|
|
1270
|
+
this.currentDataSources = dataSources;
|
|
1271
|
+
this.setSessionData({selectedDatabases:dataSources})
|
|
1272
|
+
if(JSON.stringify({dataSources:this.previousDataSources}) != JSON.stringify({dataSources})){
|
|
1273
|
+
if(isObj(this.props.dataSourceSelectorProps) && isFunction(this.props.dataSourceSelectorProps.onChange)){
|
|
1274
|
+
args.datagridContext = this;
|
|
1275
|
+
this.props.dataSourceSelectorProps.onChange(args);
|
|
1276
|
+
}
|
|
1277
|
+
this.refresh(true);
|
|
1278
|
+
}
|
|
1279
|
+
this.previousDataSources = dataSources;
|
|
1280
|
+
this.previousServer = server;
|
|
1281
|
+
}
|
|
1282
|
+
beforeFetchData(){}
|
|
1283
|
+
fetchData({fetchOptions}){
|
|
1284
|
+
return Promise.resolve(this.state.data);
|
|
1285
|
+
}
|
|
1221
1286
|
/**** Filtre le tableau */
|
|
1222
1287
|
doFilter ({value,field,selector,event,force}){
|
|
1223
1288
|
if(!this._isMounted()) return;
|
|
@@ -1247,7 +1312,7 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1247
1312
|
this._pagination.start = 0;
|
|
1248
1313
|
}
|
|
1249
1314
|
this.filtersSelectors = {selector:this.getFilters()};
|
|
1250
|
-
return this.fetchData(true,
|
|
1315
|
+
return this.fetchData({force:true,fetchOptions:this.filtersSelectors});
|
|
1251
1316
|
}
|
|
1252
1317
|
onSetQueryLimit(){
|
|
1253
1318
|
if(!this.canSetQueryLimit()) return;
|
|
@@ -1304,7 +1369,18 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1304
1369
|
forceRefresh(){
|
|
1305
1370
|
this.refresh(true);
|
|
1306
1371
|
}
|
|
1307
|
-
refresh (force,cb){
|
|
1372
|
+
refresh (force,cb){
|
|
1373
|
+
if(isFunction(force)){
|
|
1374
|
+
let t = cb;
|
|
1375
|
+
cb = force;
|
|
1376
|
+
force = isBool(t)? t : true;
|
|
1377
|
+
}
|
|
1378
|
+
return this.fetchData({force:defaultBool(force,true)}).then((data)=>{
|
|
1379
|
+
if(isFunction(cb)){
|
|
1380
|
+
cb(data);
|
|
1381
|
+
}
|
|
1382
|
+
})
|
|
1383
|
+
}
|
|
1308
1384
|
onResizePage(){}
|
|
1309
1385
|
componentDidMount(){
|
|
1310
1386
|
super.componentDidMount();
|
|
@@ -1353,12 +1429,32 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1353
1429
|
max = max ? Math.min(max,this.state.data.length,max) : this.state.data.length;
|
|
1354
1430
|
}
|
|
1355
1431
|
return max;
|
|
1432
|
+
}
|
|
1433
|
+
canSetIsLoading(){
|
|
1434
|
+
return isObj(this.progressBarRef.current) && typeof this.progressBarRef.current.setIsLoading =='function' ? true : false;
|
|
1435
|
+
}
|
|
1436
|
+
setIsLoading(loading,cb){
|
|
1437
|
+
if(this.canSetIsLoading() && typeof loading =='boolean'){
|
|
1438
|
+
return this.progressBarRef.current.setIsLoading(loading,()=>{
|
|
1439
|
+
if(typeof cb =='function'){
|
|
1440
|
+
cb();
|
|
1441
|
+
}
|
|
1442
|
+
});
|
|
1443
|
+
} else if(typeof cb =='function'){
|
|
1444
|
+
cb();
|
|
1445
|
+
}
|
|
1446
|
+
return false;
|
|
1356
1447
|
}
|
|
1357
1448
|
/**** met à jour l'état de progression de la mise à jour du tableau */
|
|
1358
|
-
updateProgress(
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
this.
|
|
1449
|
+
updateProgress(isLoading,cb){
|
|
1450
|
+
this.isLoadingRef.current = defaultBool(isLoading,!!!this.isLoadingRef.current);
|
|
1451
|
+
cb = typeof cb =='function'?cb : typeof isLoading =='function'? isLoading : null
|
|
1452
|
+
if(this.canSetIsLoading()){
|
|
1453
|
+
return this.setIsLoading(isLoading,cb);
|
|
1454
|
+
}
|
|
1455
|
+
cb && setTimeout(() => {
|
|
1456
|
+
cb();
|
|
1457
|
+
}, 500);
|
|
1362
1458
|
}
|
|
1363
1459
|
isAllRowsSelected(update){
|
|
1364
1460
|
return this.selectedRowsCount && this.selectedRowsCount === this.getMaxSelectableRows()? true : false;
|
|
@@ -1408,17 +1504,18 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1408
1504
|
return false;
|
|
1409
1505
|
}
|
|
1410
1506
|
UNSAFE_componentWillReceiveProps(nextProps){
|
|
1411
|
-
if(!
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
}
|
|
1507
|
+
if(!isObjOrArray(nextProps.data) || nextProps.data == this.props.data || stableHash(nextProps.data) == stableHash(this.props.data)) return;
|
|
1508
|
+
this.prepareData({data:nextProps.data,force:true},(state)=>{
|
|
1509
|
+
this.setState(state)
|
|
1510
|
+
});
|
|
1416
1511
|
}
|
|
1417
1512
|
getDefaultPreloader(props){
|
|
1418
1513
|
return CommonDatagridComponent.getDefaultPreloader();
|
|
1419
1514
|
}
|
|
1420
1515
|
isLoading (){
|
|
1421
|
-
|
|
1516
|
+
if(this.state.isReady === false) return true;
|
|
1517
|
+
if(typeof this.props.isLoading =='boolean') return this.props.isLoading;
|
|
1518
|
+
return this.isLoadingRef.current === true ? true : false;
|
|
1422
1519
|
}
|
|
1423
1520
|
getLinesProgressBar(){
|
|
1424
1521
|
return CommonDatagridComponent.LinesProgressBar(this.props);
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// Copyright 2022 @fto-consult/Boris Fouomene. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style
|
|
3
|
+
// license that can be found in the LICENSE file.
|
|
4
|
+
import React from "$react";
|
|
5
|
+
import {defaultBool} from "$utils";
|
|
6
|
+
|
|
7
|
+
const DatagridProgressBar = React.forwardRef(({isLoading:customIsLoading,onChange,children},ref)=>{
|
|
8
|
+
const [isLoading,_setIsLoading] = React.useState(defaultBool(customIsLoading));
|
|
9
|
+
const isMounted = React.useIsMounted();
|
|
10
|
+
const loadingCbRef = React.useRef(null);
|
|
11
|
+
const cb = loadingCbRef.current;
|
|
12
|
+
loadingCbRef.current = null;
|
|
13
|
+
const setIsLoading = (loading)=>{
|
|
14
|
+
_setIsLoading(loading);
|
|
15
|
+
}
|
|
16
|
+
const context = {
|
|
17
|
+
isLoading,
|
|
18
|
+
setIsLoading : (loading,cb)=>{
|
|
19
|
+
if(!isMounted()){
|
|
20
|
+
if(typeof cb =='function'){
|
|
21
|
+
return cb({});
|
|
22
|
+
}
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if(typeof loading =='boolean' && loading != isLoading){
|
|
26
|
+
loadingCbRef.current = cb;
|
|
27
|
+
setIsLoading(loading);
|
|
28
|
+
} else if(typeof cb =='function'){
|
|
29
|
+
cb({isLoading});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
React.setRef(ref,context);
|
|
34
|
+
React.useEffect(()=>{
|
|
35
|
+
if(typeof customIsLoading =='boolean' && customIsLoading != isLoading){
|
|
36
|
+
setIsLoading(customIsLoading);
|
|
37
|
+
}
|
|
38
|
+
},[customIsLoading])
|
|
39
|
+
React.useEffect(()=>{
|
|
40
|
+
if(typeof cb =='function'){
|
|
41
|
+
cb({isLoading});
|
|
42
|
+
}
|
|
43
|
+
loadingCbRef.current = null;
|
|
44
|
+
if(typeof onChange =='function'){
|
|
45
|
+
onChange(context);
|
|
46
|
+
}
|
|
47
|
+
},[isLoading])
|
|
48
|
+
React.useEffect(()=>{
|
|
49
|
+
return ()=>{
|
|
50
|
+
React.setRef(ref,null);
|
|
51
|
+
}
|
|
52
|
+
},[]);
|
|
53
|
+
return !isLoading || !React.isValidElement(children) ? null : children;
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
DatagridProgressBar.displayName ="DatagridProgressBar";
|
|
57
|
+
|
|
58
|
+
export default DatagridProgressBar;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import CommonDatagrid from "./Common";
|
|
2
2
|
import {defaultObj,extendObj,defaultStr,isNonNullString,isFunction,isPromise} from "$utils";
|
|
3
|
-
import actions from "$actions";
|
|
4
3
|
import PropTypes from "prop-types";
|
|
5
|
-
import stableHash from "stable-hash";
|
|
6
4
|
|
|
7
5
|
export default class CommonTableDatagrid extends CommonDatagrid{
|
|
8
6
|
constructor(props){
|
|
@@ -20,20 +18,6 @@ export default class CommonTableDatagrid extends CommonDatagrid{
|
|
|
20
18
|
tableName : {value:tableName,override:false,writable:false}
|
|
21
19
|
})
|
|
22
20
|
}
|
|
23
|
-
let isPv = this.isPivotDatagrid();
|
|
24
|
-
if(isPv){
|
|
25
|
-
isPv = this.props.dbSelector !== false;
|
|
26
|
-
} else isPv = this.props.dbSelector === true ? true : false;
|
|
27
|
-
if(isPv){
|
|
28
|
-
let dbSelectorProps = defaultObj(this.props.dbSelectorProps);
|
|
29
|
-
['table','tableName'].map((tb,idx)=>{
|
|
30
|
-
dbSelectorProps[tb] = defaultStr(this.props[tb],dbSelectorProps[tb]);
|
|
31
|
-
});
|
|
32
|
-
this.setSessionData({selectedDataSources:this.currentDataSources});
|
|
33
|
-
} else {
|
|
34
|
-
this.currentDataSources = Object.toArray(this.currentDataSources);
|
|
35
|
-
}
|
|
36
|
-
this.state.isLoading = true;
|
|
37
21
|
}
|
|
38
22
|
prepareFetchData(fetchData){
|
|
39
23
|
this.INITIAL_STATE.fetchData = defaultVal(fetchData,this.props.fetchData);
|
|
@@ -42,7 +26,7 @@ export default class CommonTableDatagrid extends CommonDatagrid{
|
|
|
42
26
|
onUpsertData =(arg) =>{
|
|
43
27
|
if(!this._isMounted()) return;
|
|
44
28
|
this.isDataJustComeToUpsert = true; ///on empêche d'afficher le progress bar
|
|
45
|
-
this.fetchData(true).finally(()=>{
|
|
29
|
+
this.fetchData({force:true}).finally(()=>{
|
|
46
30
|
this.isDataJustComeToUpsert = undefined;
|
|
47
31
|
});
|
|
48
32
|
}
|
|
@@ -52,7 +36,7 @@ export default class CommonTableDatagrid extends CommonDatagrid{
|
|
|
52
36
|
extendObj(this._events,{
|
|
53
37
|
onUpsertData : this.onUpsertData.bind(this),
|
|
54
38
|
});
|
|
55
|
-
this.fetchData(true);
|
|
39
|
+
this.fetchData({force:true});
|
|
56
40
|
}
|
|
57
41
|
|
|
58
42
|
componentWillUnmount(){
|
|
@@ -63,32 +47,7 @@ export default class CommonTableDatagrid extends CommonDatagrid{
|
|
|
63
47
|
isTableData(){
|
|
64
48
|
return true;
|
|
65
49
|
}
|
|
66
|
-
|
|
67
|
-
let {dataSources,server} = args;
|
|
68
|
-
this.currentDataSources = dataSources;
|
|
69
|
-
if(JSON.stringify({dataSources:this.previousDataSources}) != JSON.stringify({dataSources})){
|
|
70
|
-
if(isObj(this.props.dbSelectorProps) && isFunction(this.props.dbSelectorProps.onChange)){
|
|
71
|
-
args.datagridContext = this;
|
|
72
|
-
this.props.dbSelectorProps.onChange(args);
|
|
73
|
-
}
|
|
74
|
-
this.refresh(true);
|
|
75
|
-
}
|
|
76
|
-
this.previousDataSources = dataSources;
|
|
77
|
-
this.previousServer = server;
|
|
78
|
-
}
|
|
79
|
-
refresh (force,cb){
|
|
80
|
-
if(isFunction(force)){
|
|
81
|
-
let t = cb;
|
|
82
|
-
cb = force;
|
|
83
|
-
force = isBool(t)? t : true;
|
|
84
|
-
}
|
|
85
|
-
force = defaultBool(force,true)
|
|
86
|
-
return this.fetchData(undefined,force).then((data)=>{
|
|
87
|
-
if(isFunction(cb)){
|
|
88
|
-
cb(data);
|
|
89
|
-
}
|
|
90
|
-
})
|
|
91
|
-
}
|
|
50
|
+
|
|
92
51
|
getProgressBar(props){
|
|
93
52
|
if(this.isDataJustComeToUpsert) return null;
|
|
94
53
|
return super.getProgressBar(props);
|
|
@@ -101,35 +60,16 @@ export default class CommonTableDatagrid extends CommonDatagrid{
|
|
|
101
60
|
la table dans la base common.
|
|
102
61
|
Elle pourra éventuellement passer directement la limite et les filtres à la fonction fetchdata
|
|
103
62
|
*/
|
|
104
|
-
fetchData (cb,force,fetchOptions){
|
|
105
|
-
if(!this._isMounted()) return Promise.resolve(
|
|
63
|
+
fetchData ({cb,callback,force,fetchOptions}){
|
|
64
|
+
if(!this._isMounted()) return Promise.resolve(this.state.data);
|
|
106
65
|
if(this.isFetchingData) {
|
|
107
66
|
if(!isPromise(this.fetchingPromiseData)){
|
|
108
|
-
this.fetchingPromiseData = Promise.resolve(
|
|
67
|
+
this.fetchingPromiseData = Promise.resolve(this.state.data)
|
|
109
68
|
}
|
|
110
69
|
return this.fetchingPromiseData;
|
|
111
70
|
};
|
|
112
71
|
this.isFetchingData = true;
|
|
113
|
-
|
|
114
|
-
let t = cb;
|
|
115
|
-
if(!isObj(fetchOptions)){
|
|
116
|
-
fetchOptions = cb;
|
|
117
|
-
}
|
|
118
|
-
if(isBool(t)){
|
|
119
|
-
let t1 = force;
|
|
120
|
-
force = t;
|
|
121
|
-
if(isFunction(t1)){
|
|
122
|
-
cb = t1;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
if(isBool(cb)){
|
|
127
|
-
let t = force;
|
|
128
|
-
force = cb;
|
|
129
|
-
if(isFunction(t)){
|
|
130
|
-
cb = t;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
72
|
+
cb = typeof cb =='function'? cb : typeof callback =='function'? callback : undefined;
|
|
133
73
|
this.fetchingPromiseData = new Promise((resolve,reject)=>{
|
|
134
74
|
setTimeout(()=>{
|
|
135
75
|
if(typeof cb === 'boolean'){
|
|
@@ -139,11 +79,10 @@ export default class CommonTableDatagrid extends CommonDatagrid{
|
|
|
139
79
|
if(force !== true && isArray(this.INITIAL_STATE.data)) {
|
|
140
80
|
return this.resolveFetchedDataPromise({cb,data:this.INITIAL_STATE.data}).then(resolve).catch(reject)
|
|
141
81
|
}
|
|
142
|
-
|
|
82
|
+
const fetchFilters = this.getFilters();
|
|
143
83
|
fetchOptions = isObj(fetchOptions)?Object.clone(fetchOptions):{};
|
|
144
84
|
fetchOptions.selector = defaultObj(fetchOptions.selector);
|
|
145
85
|
fetchOptions.dataSources = this.currentDataSources;
|
|
146
|
-
const fetchFilters = this.getFilters();
|
|
147
86
|
fetchOptions = extendObj(true,true,{},fetchOptions,{selector : fetchFilters});
|
|
148
87
|
fetchOptions.dataSources = this.currentDataSources;
|
|
149
88
|
fetchOptions.sort = this.state.sort;
|
|
@@ -155,12 +94,18 @@ export default class CommonTableDatagrid extends CommonDatagrid{
|
|
|
155
94
|
delete fetchOptions.limit
|
|
156
95
|
}
|
|
157
96
|
}
|
|
97
|
+
this.beforeFetchData(fetchOptions);
|
|
98
|
+
if(typeof this.props.beforeFetchData =='function' && this.props.beforeFetchData({context:this,fetchOptions,options:fetchOptions}) === false){
|
|
99
|
+
this.isFetchingData = false;
|
|
100
|
+
return resolve(this.state.data);
|
|
101
|
+
}
|
|
102
|
+
let fetchData = this.INITIAL_STATE.fetchData;
|
|
158
103
|
if(isFunction(this.props.fetchData)){
|
|
159
104
|
/**** l'on peut définir la props fetchData, qui est la fonction appelée pour la recherche des données */
|
|
160
105
|
fetchData = this.props.fetchData.call(this,fetchOptions);
|
|
161
106
|
}
|
|
162
107
|
fetchData = isFunction(fetchData)? fetchData.call(this,fetchOptions) : fetchData;
|
|
163
|
-
this.updateProgress(
|
|
108
|
+
this.updateProgress(true,()=>{
|
|
164
109
|
if(isPromise(fetchData)){
|
|
165
110
|
return fetchData.then(data=>{
|
|
166
111
|
return this.resolveFetchedDataPromise({cb,data,force}).then((data)=>{
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Copyright 2022 @fto-consult/Boris Fouomene. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style
|
|
3
|
+
// license that can be found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
import Accordion,{ TableData as TableDataAccordion} from "./Accordion";
|
|
6
|
+
import Table,{TableData as DatagridTableData} from "./Table";
|
|
7
|
+
import {isDesktopMedia,isMobileMedia} from "$cplatform/dimensions";
|
|
8
|
+
import {isFunction,defaultVal} from "$utils";
|
|
9
|
+
import React from "$react";
|
|
10
|
+
import {getRenderType} from "./utils";
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
const DatagridMainComponent = React.forwardRef((props,ref)=>{
|
|
14
|
+
const isDesk = isDesktopMedia();
|
|
15
|
+
const isMob = isMobileMedia();
|
|
16
|
+
const isTableDataRef = React.useRef(defaultVal(props.isTableData,defaultStr(props.tableName,props.table) || typeof props.fetchData ==='function'?true : false));
|
|
17
|
+
const TableComponent = isTableDataRef.current ? DatagridTableData : Table;
|
|
18
|
+
const AccordionComponent = isTableDataRef.current ? TableDataAccordion : Accordion;
|
|
19
|
+
let Component = TableComponent;
|
|
20
|
+
const canRenderAccordion = (isFunction(props.accordion) || (isObj(props.accordionProps) && isFunction(props.accordionProps.accordion)) || props.accordion === true);
|
|
21
|
+
let renderType = defaultStr(getRenderType(),isDesk? "fixed":'accordion').trim().toLowerCase()
|
|
22
|
+
if(renderType == 'accordion' && canRenderAccordion){
|
|
23
|
+
Component = AccordionComponent;
|
|
24
|
+
} else if(renderType =='table'){
|
|
25
|
+
Component = TableComponent;
|
|
26
|
+
} else if(isMob && canRenderAccordion){
|
|
27
|
+
Component = AccordionComponent;
|
|
28
|
+
}
|
|
29
|
+
return <Component
|
|
30
|
+
{...props}
|
|
31
|
+
ref = {ref}
|
|
32
|
+
/>;
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export default DatagridMainComponent;
|
|
36
|
+
|
|
37
|
+
DatagridMainComponent.displayName = "DatagridMainComponent";
|
|
38
|
+
|
|
39
|
+
DatagridMainComponent.propTypes = {
|
|
40
|
+
...DatagridTableData.propTypes
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
DatagridMainComponent.getDBName = DatagridTableData.getDBName;
|
|
44
|
+
|
|
45
|
+
DatagridMainComponent.LinesProgressBar = DatagridMainComponent.LineProgressBar = DatagridTableData.LineProgressBar;
|