@fto-consult/expo-ui 6.26.2 → 6.26.4
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/components/Datagrid/Accordion/Filters.js +36 -38
- package/src/components/Datagrid/Common/Common.js +5 -2
- package/src/components/Datagrid/SWRDatagrid.js +22 -53
- package/src/components/Dialog/AppBarDialog.js +2 -1
- package/src/components/ErrorBoundary/ErrorMessage.js +3 -2
- package/src/components/ErrorBoundary/Provider.js +4 -3
- package/src/components/ErrorBoundary/index.js +1 -0
- package/src/components/Filter/index.js +1 -0
- package/src/components/Form/Fields/Field.js +3 -2
- package/src/components/Form/Fields/IdField.js +38 -28
- package/src/components/Form/FormData/componentsTypes.js +11 -4
- package/src/components/Icon/Icon.js +1 -1
- package/src/components/List/Virtuoso/index.js +1 -2
- package/src/components/Logo/Progress.js +9 -5
- package/src/components/Menu/Menu.js +113 -97
- package/src/components/Portal/Portal.js +88 -0
- package/src/components/Portal/PortalHost.js +31 -0
- package/src/components/Portal/PortalProvider.js +31 -0
- package/src/components/Portal/constants.js +15 -0
- package/src/components/Portal/context.js +10 -0
- package/src/components/Portal/hooks.js +75 -0
- package/src/components/Portal/index.js +11 -3
- package/src/components/Portal/index.old.js +4 -0
- package/src/components/Portal/reducer.js +92 -0
- package/src/components/Portal/usePortalState.js +19 -0
- package/src/components/Preloader/index.js +1 -1
- package/src/components/ScrollView/index.js +1 -0
- package/src/components/SplashScreen/index.js +2 -2
- package/src/components/StatusBar/Component/index.web.js +0 -1
- package/src/components/Table/EmptyPlaceholder/index.js +41 -0
- package/src/components/Table/EmptyPlaceholder/index.native.js +3 -0
- package/src/components/Table/hooks.js +1 -1
- package/src/components/Table/index.js +13 -7
- package/src/components/TextField/index.js +1 -0
- package/src/context/Provider.js +7 -0
- package/src/context/hooks.js +1 -2
- package/src/context/query.js +92 -0
- package/src/index.js +34 -41
- package/src/navigation/index.js +2 -1
- package/src/screens/Help/openLibraries.js +1 -1
- package/src/components/Icon/IconButton.js +0 -155
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fto-consult/expo-ui",
|
|
3
|
-
"version": "6.26.
|
|
3
|
+
"version": "6.26.4",
|
|
4
4
|
"description": "Bibliothèque de composants UI Expo,react-native",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"@expo/html-elements": "^0.5.1",
|
|
69
69
|
"@expo/vector-icons": "^13.0.0",
|
|
70
70
|
"@faker-js/faker": "^8.0.2",
|
|
71
|
-
"@fto-consult/common": "^3.
|
|
71
|
+
"@fto-consult/common": "^3.29.1",
|
|
72
72
|
"@gorhom/portal": "^1.0.14",
|
|
73
73
|
"@pchmn/expo-material3-theme": "^1.3.1",
|
|
74
74
|
"@react-native-async-storage/async-storage": "1.18.2",
|
|
@@ -2,7 +2,7 @@ import {Content} from "$ecomponents/BottomSheet";
|
|
|
2
2
|
import Icon from "$ecomponents/Icon";
|
|
3
3
|
import React from "$react";
|
|
4
4
|
import {defaultStr,defaultBool,defaultObj} from "$cutils";
|
|
5
|
-
import Filter, {canHandleFilter
|
|
5
|
+
import Filter, {canHandleFilter} from "$ecomponents/Filter";
|
|
6
6
|
import PropTypes from "prop-types";
|
|
7
7
|
import { StyleSheet,View } from "react-native";
|
|
8
8
|
import Menu from "$ecomponents/Menu";
|
|
@@ -18,16 +18,14 @@ const MIN_WIDTH = 250;
|
|
|
18
18
|
let windowWidth = Dimensions.get("window").width;
|
|
19
19
|
|
|
20
20
|
const FiltersAccordionComponent = React.forwardRef((props,ref)=>{
|
|
21
|
-
const {filters,isLoading,filteredColumns,children,label,filterTitle:customFilterTitle,visible:customVisible,orOperator,andOperator,onToggleFilters,context:customContext,...restProps} = props;
|
|
21
|
+
const {filters,isLoading,filteredColumns,children,label,testID:cTestID,filterTitle:customFilterTitle,visible:customVisible,orOperator,andOperator,onToggleFilters,context:customContext,...restProps} = props;
|
|
22
22
|
const context = defaultObj(customContext);
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
});
|
|
23
|
+
const testID = defaultStr(testID,"RN_AccordionFilters");
|
|
24
|
+
const [visibleColumns,setVisibleColumns] = React.useState(filteredColumns);
|
|
25
|
+
const [visible,setVisible] = React.useState(defaultBool(customVisible,false));
|
|
27
26
|
const valuesRefs = React.useRef({});
|
|
28
27
|
windowWidth = Dimensions.get("window").width;
|
|
29
28
|
const innerRef = React.useRef(null);
|
|
30
|
-
const {visible,visibleColumns} = state;
|
|
31
29
|
const rest = defaultObj(restProps);
|
|
32
30
|
const filterTitle = defaultStr(customFilterTitle,'Filtres');
|
|
33
31
|
const canHandlerFilterRef = React.useRef(0);
|
|
@@ -50,8 +48,8 @@ const FiltersAccordionComponent = React.forwardRef((props,ref)=>{
|
|
|
50
48
|
if(React.isValidElement(filter)){
|
|
51
49
|
content.push(<Grid.Cell {...cellProps} key={index}>{filter}</Grid.Cell>)
|
|
52
50
|
} else if(isObj(filter)){
|
|
53
|
-
const {onChange} = filter;
|
|
54
|
-
const key = defaultStr(filter.key,filter.field,filter.index,index+"");
|
|
51
|
+
const {onChange,visible:cVisible,...rest} = filter;
|
|
52
|
+
const key = defaultStr(filter.key,filter.field,filter.columnField,filter.index,index+"");
|
|
55
53
|
const visible = !!visibleColumns[key];
|
|
56
54
|
colMenus.push(<Menu.Item
|
|
57
55
|
key = {key}
|
|
@@ -61,7 +59,7 @@ const FiltersAccordionComponent = React.forwardRef((props,ref)=>{
|
|
|
61
59
|
if(context.toggleFilterColumnVisibility){
|
|
62
60
|
context.toggleFilterColumnVisibility(key,!visible);
|
|
63
61
|
}
|
|
64
|
-
|
|
62
|
+
setVisibleColumns({...visibleColumns,[key]:!visible});
|
|
65
63
|
}}
|
|
66
64
|
/>)
|
|
67
65
|
if(!visible) {
|
|
@@ -72,32 +70,32 @@ const FiltersAccordionComponent = React.forwardRef((props,ref)=>{
|
|
|
72
70
|
if(renderMenusOnly) return null;
|
|
73
71
|
content.push(
|
|
74
72
|
<Grid.Cell {...cellProps} key={key}>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
73
|
+
<Filter
|
|
74
|
+
{...rest}
|
|
75
|
+
{...(isObj(valuesRefs.current[key]) ? valuesRefs.current[key] : {})}
|
|
76
|
+
dynamicRendered
|
|
77
|
+
//isLoading = {isLoading && filteredRef.current[key] ? true : false}
|
|
78
|
+
orOperator = {defaultBool(orOperator,filter.orOperator,true)}
|
|
79
|
+
andOperator = {defaultBool(andOperator,filter.andOperator,true)}
|
|
80
|
+
onChange = {(arg)=>{
|
|
81
|
+
if(!arg.action && !arg.operator || !arg.field) return;
|
|
82
|
+
const canHandle = canHandleFilter(arg);
|
|
83
|
+
valuesRefs.current[key] = arg;
|
|
84
|
+
if(filteredRef.current[key] !== canHandle){
|
|
85
|
+
if(canHandle){
|
|
86
|
+
canHandlerFilterRef.current++;
|
|
87
|
+
} else {
|
|
88
|
+
canHandlerFilterRef.current = Math.max(0,canHandlerFilterRef.current-1);
|
|
89
|
+
}
|
|
91
90
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
inputProps = {{containerProps}}
|
|
91
|
+
filteredRef.current[key] = canHandle;
|
|
92
|
+
if(onChange){
|
|
93
|
+
onChange(arg);
|
|
94
|
+
}
|
|
95
|
+
}}
|
|
96
|
+
withBottomSheet
|
|
97
|
+
containerProps = {{...containerProps}}
|
|
98
|
+
inputProps = {{containerProps}}
|
|
101
99
|
/></Grid.Cell>)
|
|
102
100
|
}
|
|
103
101
|
})
|
|
@@ -115,7 +113,7 @@ const FiltersAccordionComponent = React.forwardRef((props,ref)=>{
|
|
|
115
113
|
title = {null}
|
|
116
114
|
visible = {visible}
|
|
117
115
|
onDissmiss = {()=>{
|
|
118
|
-
|
|
116
|
+
setVisible(false);
|
|
119
117
|
}}
|
|
120
118
|
anchor = {(props)=><Tooltip title = {mainFilterTitle}Component={Pressable} {...props} style={[theme.styles.row]}>
|
|
121
119
|
<Icon
|
|
@@ -132,8 +130,8 @@ const FiltersAccordionComponent = React.forwardRef((props,ref)=>{
|
|
|
132
130
|
>
|
|
133
131
|
{({open,close})=>{
|
|
134
132
|
const {content,colMenus} = prepareContent(filters);
|
|
135
|
-
return <View style={[styles.wrapper]}>
|
|
136
|
-
<View style = {[styles.menuWrapper]}>
|
|
133
|
+
return <View style={[styles.wrapper]} testID={testID+"_AccordionFiltersWrapper"}>
|
|
134
|
+
<View style = {[styles.menuWrapper]} testID={testID+"_AccordionFilterWraperContent"}>
|
|
137
135
|
<Expandable
|
|
138
136
|
left = {(props)=><Icon {...props} icon={content.length?'filter-plus':'filter-menu'}/>}
|
|
139
137
|
style = {styles.expandable}
|
|
@@ -2560,7 +2560,6 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
2560
2560
|
sortedProps,
|
|
2561
2561
|
width,
|
|
2562
2562
|
columnField : field,
|
|
2563
|
-
//columnDef : header,
|
|
2564
2563
|
index : headerIndex,
|
|
2565
2564
|
visible,
|
|
2566
2565
|
key : header.field,
|
|
@@ -3617,9 +3616,13 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
3617
3616
|
return false;
|
|
3618
3617
|
}
|
|
3619
3618
|
UNSAFE_componentWillReceiveProps(nextProps){
|
|
3620
|
-
if(
|
|
3619
|
+
if(nextProps.data === this.props.data || React.areEquals(nextProps.data,this.props.data)) {
|
|
3621
3620
|
return false;
|
|
3622
3621
|
}
|
|
3622
|
+
const newStableHash = stableHash(nextProps.data);
|
|
3623
|
+
this.prevStableDataHash = this.prevStableDataHash !== undefined ? this.prevStableDataHash : stableHash(this.props.data);
|
|
3624
|
+
if(newStableHash == this.prevStableDataHash) return false;
|
|
3625
|
+
this.prevStableDataHash = newStableHash;
|
|
3623
3626
|
this.setIsLoading(true,true);
|
|
3624
3627
|
this.prepareData({...nextProps,force:true},(state)=>{
|
|
3625
3628
|
this.setState(state)
|
|
@@ -151,7 +151,6 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
|
151
151
|
title
|
|
152
152
|
},rest.exportTableProps.pdf);
|
|
153
153
|
const fetchOptionsRef = React.useRef(defaultObj(customFetchOptions));
|
|
154
|
-
const refreshCBRef = React.useRef(null);
|
|
155
154
|
const fPathRef = React.useRef(defaultStr(fetchPathKey,uniqid("fetchPath")));
|
|
156
155
|
fetchPath = defaultStr(fetchPath,table.queryPath,tableName.toLowerCase()).trim();
|
|
157
156
|
if(fetchPath){
|
|
@@ -160,23 +159,16 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
|
160
159
|
const sortRef = React.useRef({});
|
|
161
160
|
const innerRef = React.useRef(null);
|
|
162
161
|
const showProgressRef = React.useRef(true);
|
|
163
|
-
const dataRef = React.useRef([]);
|
|
164
|
-
const hasResultRef = React.useRef(false);
|
|
165
|
-
const totalRef = React.useRef(0);
|
|
166
|
-
const isFetchingRef = React.useRef(false);
|
|
167
162
|
const pageRef = React.useRef(1);
|
|
168
163
|
const canHandlePagination = handlePagination !== false ? true : false;
|
|
169
164
|
const canHandleLimit = handleQueryLimit !== false && canHandlePagination ? true : false;
|
|
170
165
|
const limitRef = React.useRef(!canHandleLimit ?0 : defaultNumber(getSessionData("limit"),500));
|
|
171
166
|
const isInitializedRef = React.useRef(false);
|
|
172
167
|
testID = defaultStr(testID,"RNSWRDatagridComponent");
|
|
173
|
-
const
|
|
174
|
-
const {error, isValidating,isLoading:customIsLoading,refresh} = useSWR(fetchPath,{
|
|
168
|
+
const {error, isValidating,isLoading,data:result,refresh} = useSWR(fetchPath,{
|
|
175
169
|
fetcher : (url,opts)=>{
|
|
176
170
|
if(!isInitializedRef.current) {
|
|
177
|
-
|
|
178
|
-
isLoadingRef.current = false;
|
|
179
|
-
return;
|
|
171
|
+
return Promise.resolve({data:[],total:0});
|
|
180
172
|
}
|
|
181
173
|
opts = defaultObj(opts);
|
|
182
174
|
opts.fetchOptions = isObj(opts.fetchOptions)? Object.clone(opts.fetchOptions) : {};
|
|
@@ -195,35 +187,14 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
|
195
187
|
delete opts.page;
|
|
196
188
|
delete opts.offset;
|
|
197
189
|
}
|
|
198
|
-
const fetchCB = (fArgs)=>{
|
|
199
|
-
let {data,total} = (Array.isArray(fArgs) ? {data:fArgs,total:fArgs.length} : isObj(fArgs)? fArgs : {data:[],total:0});
|
|
200
|
-
totalRef.current = total;
|
|
201
|
-
dataRef.current = data;
|
|
202
|
-
const dd = Object.size(data);
|
|
203
|
-
if(dd>total){
|
|
204
|
-
total = dd;
|
|
205
|
-
}
|
|
206
|
-
hasResultRef.current = true;
|
|
207
|
-
if(onFetchData && typeof onFetchData =='function'){
|
|
208
|
-
onFetchData({allData:data,total,data,context:innerRef.current})
|
|
209
|
-
}
|
|
210
|
-
return data;
|
|
211
|
-
};
|
|
212
|
-
hasResultRef.current = false;
|
|
213
|
-
isFetchingRef.current = true;
|
|
214
190
|
if(typeof fetcher =='function'){
|
|
215
|
-
return fetcher(url,opts)
|
|
216
|
-
isFetchingRef.current = false;
|
|
217
|
-
isLoadingRef.current = false;
|
|
218
|
-
});
|
|
191
|
+
return fetcher(url,opts);
|
|
219
192
|
}
|
|
220
193
|
const {url:fUrl,fetcher:cFetcher,...rest} = getFetcherOptions(url,opts);
|
|
221
194
|
if(showProgressRef.current ===false){
|
|
222
195
|
rest.showError = false;
|
|
223
196
|
}
|
|
224
|
-
return cFetcher(fUrl,rest).
|
|
225
|
-
isFetchingRef.current = false;
|
|
226
|
-
}).catch((e)=>{
|
|
197
|
+
return cFetcher(fUrl,rest).catch((e)=>{
|
|
227
198
|
console.log(e," is swr fetching data");
|
|
228
199
|
throw e;
|
|
229
200
|
});
|
|
@@ -231,39 +202,38 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
|
231
202
|
showError : false,
|
|
232
203
|
swrOptions : getSWROptions(swrConfig.refreshTimeout)
|
|
233
204
|
});
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
cb();
|
|
205
|
+
const {data,total} = React.useMemo(()=>{
|
|
206
|
+
const {data,total} = (Array.isArray(result) ? {data:result,total:result.length} : isObj(result)? result : {data:[],total:0});
|
|
207
|
+
const dd = Object.size(data);
|
|
208
|
+
if(dd>total){
|
|
209
|
+
total = dd;
|
|
210
|
+
}
|
|
211
|
+
if(onFetchData && typeof onFetchData =='function'){
|
|
212
|
+
onFetchData({allData:data,total,data,context:innerRef.current})
|
|
243
213
|
}
|
|
244
|
-
|
|
214
|
+
return {data,total};
|
|
215
|
+
},[result])
|
|
216
|
+
const loading = (isLoading || isValidating);
|
|
245
217
|
React.useEffect(()=>{
|
|
246
218
|
setTimeout(x=>{
|
|
247
219
|
if(error && innerRef.current && innerRef.current.isLoading && innerRef.current.isLoading()){
|
|
248
220
|
innerRef.current.setIsLoading(false,false);
|
|
249
221
|
}
|
|
250
|
-
},500)
|
|
251
|
-
},[error])
|
|
222
|
+
},500);
|
|
223
|
+
},[error]);
|
|
252
224
|
const doRefresh = (showProgress)=>{
|
|
253
225
|
showProgressRef.current = showProgress ? typeof showProgress ==='boolean' : false;
|
|
254
|
-
if(isFetchingRef.current) return;
|
|
255
|
-
isLoadingRef.current = true;
|
|
256
226
|
refresh();
|
|
257
227
|
}
|
|
258
228
|
const canPaginate = ()=>{
|
|
259
229
|
if(!canHandlePagination) return false;
|
|
260
|
-
if(canHandleLimit && typeof
|
|
230
|
+
if(canHandleLimit && typeof total !=='number' || typeof pageRef.current !='number' || typeof limitRef.current !='number') return false;
|
|
261
231
|
if(limitRef.current <= 0) return false;
|
|
262
232
|
return true;
|
|
263
233
|
}
|
|
264
234
|
const getTotalPages = ()=>{
|
|
265
235
|
if(!canPaginate()) return false;
|
|
266
|
-
return Math.ceil(
|
|
236
|
+
return Math.ceil(total / limitRef.current);;
|
|
267
237
|
};
|
|
268
238
|
const getNextPage = ()=>{
|
|
269
239
|
if(!canPaginate()) return false;
|
|
@@ -289,9 +259,8 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
|
289
259
|
}, canSortRemotely = ()=>{
|
|
290
260
|
if(!canPaginate() || autoSort === true) return false;
|
|
291
261
|
///si le nombre total d'élements est inférieur au nombre limite alors le trie peut être fait localement
|
|
292
|
-
return
|
|
262
|
+
return total > limitRef.current && true || false;
|
|
293
263
|
}
|
|
294
|
-
const loading = (isLoadingRef.current && (isLoading|| isValidating));
|
|
295
264
|
const pointerEvents = loading ?"node" : "auto";
|
|
296
265
|
const itLimits = [{
|
|
297
266
|
text : "Limite nbre elts par page",
|
|
@@ -378,7 +347,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
|
378
347
|
/>
|
|
379
348
|
<View testID={testID+"_PaginationLabel"}>
|
|
380
349
|
<Label style={{fontSize:15}}>
|
|
381
|
-
{(
|
|
350
|
+
{(total?page:0).formatNumber()}-{totalPages.formatNumber()}{" / "}{total.formatNumber()}
|
|
382
351
|
</Label>
|
|
383
352
|
</View>
|
|
384
353
|
<Icon
|
|
@@ -433,7 +402,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
|
433
402
|
isSWRDatagrid
|
|
434
403
|
isTableData
|
|
435
404
|
fetchData = {undefined}
|
|
436
|
-
data = {
|
|
405
|
+
data = {data}
|
|
437
406
|
canMakePhoneCall={canMakePhoneCall}
|
|
438
407
|
key={tableName}
|
|
439
408
|
sessionName={defaultStr(sessionName,'list-data')}
|
|
@@ -9,8 +9,9 @@ const AppBarDialogComponent = React.forwardRef((props,ref)=>{
|
|
|
9
9
|
const forceRender = React.useForceRender();
|
|
10
10
|
React.useEffect(()=>{
|
|
11
11
|
const onResize = ()=>{
|
|
12
|
+
return;
|
|
12
13
|
forceRender();
|
|
13
|
-
|
|
14
|
+
}
|
|
14
15
|
if(responsive){
|
|
15
16
|
APP.on(APP.EVENTS.RESIZE_PAGE,onResize);
|
|
16
17
|
}
|
|
@@ -13,6 +13,7 @@ import {isWeb} from "$cplatform";
|
|
|
13
13
|
|
|
14
14
|
const ErrorMessage = React.forwardRef(function(props,ref){
|
|
15
15
|
const { error,resetError,onGoBack, info } = props
|
|
16
|
+
const testID = defaultStr(props.testID,"RN_ErrorBoundaryMessage");
|
|
16
17
|
const goToHome = ()=> {
|
|
17
18
|
if(navigationRef){
|
|
18
19
|
navigationRef.navigate(homeRoute);
|
|
@@ -26,8 +27,8 @@ const ErrorMessage = React.forwardRef(function(props,ref){
|
|
|
26
27
|
const pointerEvents = 'auto';
|
|
27
28
|
const {width,height} = useWindowDimensions();
|
|
28
29
|
return <Portal>
|
|
29
|
-
<View ref={ref} testID=
|
|
30
|
-
<View style={styles.content} pointerEvents={pointerEvents}>
|
|
30
|
+
<View ref={ref} testID={`${testID}_ErrorMessageContainer`} pointerEvents={pointerEvents} style={[styles.container,isWeb()?{position:'fixed'}:null,{backgroundColor:theme.colors.surface,width,height}]}>
|
|
31
|
+
<View style={styles.content} testID={`${testID}_ErrorMessageContentContainer`} pointerEvents={pointerEvents}>
|
|
31
32
|
<Label style={styles.title}>Oops!</Label>
|
|
32
33
|
<Label style={styles.subtitle}>{'Une erreur est survenue'}</Label>
|
|
33
34
|
<Label style={styles.error}>{error.toString()}</Label>
|
|
@@ -4,6 +4,7 @@ let providerRef = null;
|
|
|
4
4
|
import * as React from "react";
|
|
5
5
|
import useForceRender from "$react/useForceRender";
|
|
6
6
|
import setRef from "$react/setRef";
|
|
7
|
+
import {defaultStr} from "$cutils";
|
|
7
8
|
|
|
8
9
|
const providerState = {};
|
|
9
10
|
|
|
@@ -38,9 +39,9 @@ const Provider = React.forwardRef((_props,innerRef)=>{
|
|
|
38
39
|
},
|
|
39
40
|
});
|
|
40
41
|
setRef(ref,context);
|
|
41
|
-
|
|
42
|
-
return <Portal>
|
|
43
|
-
<ErrorMessage {...propRef.current} ref={el=>{
|
|
42
|
+
const testID = defaultStr(propRef.current?.testID,_props.testID,"RN_ErrorBoundaryProvider");
|
|
43
|
+
return <Portal testID={testID}>
|
|
44
|
+
<ErrorMessage {...propRef.current} testID={testID+"_ErrorBoundaryPortalContent"} ref={el=>{
|
|
44
45
|
messageRef.current = el;
|
|
45
46
|
setRef(propRef.current.messageRef);
|
|
46
47
|
}}/>
|
|
@@ -245,6 +245,7 @@ export default class Field extends AppComponent {
|
|
|
245
245
|
return false;
|
|
246
246
|
}
|
|
247
247
|
callOnChange(args){
|
|
248
|
+
args.isFilter = this.isFilter();
|
|
248
249
|
if(typeof this.props.onChange === "function" && this.hasValueChanged(args.value)){
|
|
249
250
|
this.props.onChange(args);
|
|
250
251
|
}
|
|
@@ -278,7 +279,7 @@ export default class Field extends AppComponent {
|
|
|
278
279
|
actions[k][action]();
|
|
279
280
|
}
|
|
280
281
|
let form = Forms.getForm(this.formName);
|
|
281
|
-
this.INITIAL_STATE.onValidate.call(this,{...defaultObj(rest),props:this.props,formName:this.formName,form,name:this.name,field:this.name,value,event,context:this});
|
|
282
|
+
this.INITIAL_STATE.onValidate.call(this,{...defaultObj(rest),isFilter:this.isFilter(),props:this.props,formName:this.formName,form,name:this.name,field:this.name,value,event,context:this});
|
|
282
283
|
this.callOnChange({value,event,isValid:true,...rest});
|
|
283
284
|
if(form && form.props){
|
|
284
285
|
if(canEnable){
|
|
@@ -351,7 +352,7 @@ export default class Field extends AppComponent {
|
|
|
351
352
|
for(var k in actions){
|
|
352
353
|
actions[k].disable();
|
|
353
354
|
}
|
|
354
|
-
this.INITIAL_STATE.onNoValidate.call(this,{...defaultObj(rest),props:this.props,msg,value,formName:this.formName,field:this.name,name:this.name,context:this,event,validRule,validType:validRule,validParams,context:this});
|
|
355
|
+
this.INITIAL_STATE.onNoValidate.call(this,{...defaultObj(rest),isFilter:this.isFilter(),props:this.props,msg,value,formName:this.formName,field:this.name,name:this.name,context:this,event,validRule,validType:validRule,validParams,context:this});
|
|
355
356
|
let form = Forms.getForm(this.formName);
|
|
356
357
|
this.callOnChange({value,validRule,validParams,event,isValid:false,...rest});
|
|
357
358
|
if(form){
|
|
@@ -29,6 +29,9 @@ export default class FormIDField extends TextField {
|
|
|
29
29
|
|
|
30
30
|
/*** met à jour la données du numéro de piece */
|
|
31
31
|
fetchNewId(focus){
|
|
32
|
+
if(this.isFilter()){
|
|
33
|
+
return Promise.resolve("");
|
|
34
|
+
}
|
|
32
35
|
const data = defaultObj(this.props.data);
|
|
33
36
|
if(!isNonNullString(this.name)) return undefined;
|
|
34
37
|
const cb = (value)=>{
|
|
@@ -66,41 +69,48 @@ export default class FormIDField extends TextField {
|
|
|
66
69
|
return false;
|
|
67
70
|
}
|
|
68
71
|
componentDidUpdate(){
|
|
69
|
-
if(!isNonNullString(this.newFieldIdValue)){
|
|
72
|
+
if(!this.isFilter() && !isNonNullString(this.newFieldIdValue)){
|
|
70
73
|
this.fetchNewId();
|
|
71
74
|
}
|
|
72
75
|
}
|
|
73
76
|
_render(props,setRef){
|
|
74
77
|
delete props.validType;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
props.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if(typeof props.minLength !=='number'){
|
|
84
|
-
props.minLength = 2;
|
|
85
|
-
}
|
|
86
|
-
const defValue = props.defaultValue = isNonNullString(props.defaultValue)? props.defaultValue : isNonNullString(this.newFieldIdValue)? this.newFieldIdValue : undefined;
|
|
87
|
-
props.validRule = props.validType;
|
|
88
|
-
props.contentContainerProps = Object.assign({},props.contentContainerProps)
|
|
89
|
-
props.contentContainerProps.pointerEvents = defaultStr(props.contentContainerProps.pointerEvents,"auto");
|
|
90
|
-
props.enableCopy = typeof props.enableCopy ==='boolean'? props.enableCopy : (props.defaultValue || this.newFieldIdValue ? true : false);
|
|
91
|
-
const {right} = props;
|
|
92
|
-
props.readOnly = typeof props.disabled ==='boolean' ? !!!props.disabled : typeof props.readOnly =="boolean"? !!!props.disabled : false;
|
|
93
|
-
props.right = (props)=>{
|
|
94
|
-
const r = typeof right =='function'? right (props) : React.isValidElement(right)? right : null;
|
|
95
|
-
if(!defValue){
|
|
96
|
-
return <>{r}<ActivityIndicator
|
|
97
|
-
{...props}
|
|
98
|
-
style = {[props.style,{marginRight:10}]}
|
|
99
|
-
/></>
|
|
78
|
+
if(!this.isFilter()){
|
|
79
|
+
const upper = props.upper !== false ? UPPER_CASE : "";
|
|
80
|
+
if(isNonNullString(this.name) && isObj(props.data) && isNonNullString(props.data[this.name])){
|
|
81
|
+
props.disabled = true;
|
|
82
|
+
props.validType = upper;
|
|
83
|
+
props.defaultValue = props.data[this.name];
|
|
84
|
+
} else {
|
|
85
|
+
props.validType = 'required|'+upper;
|
|
100
86
|
}
|
|
101
|
-
|
|
87
|
+
if(typeof props.minLength !=='number'){
|
|
88
|
+
props.minLength = 2;
|
|
89
|
+
}
|
|
90
|
+
const defValue = props.defaultValue = isNonNullString(props.defaultValue)? props.defaultValue : isNonNullString(this.newFieldIdValue)? this.newFieldIdValue : undefined;
|
|
91
|
+
props.validRule = props.validType;
|
|
92
|
+
props.contentContainerProps = Object.assign({},props.contentContainerProps)
|
|
93
|
+
props.contentContainerProps.pointerEvents = defaultStr(props.contentContainerProps.pointerEvents,"auto");
|
|
94
|
+
props.enableCopy = typeof props.enableCopy ==='boolean'? props.enableCopy : (props.defaultValue || this.newFieldIdValue ? true : false);
|
|
95
|
+
props.readOnly = typeof props.disabled ==='boolean' ? !!!props.disabled : typeof props.readOnly =="boolean"? !!!props.disabled : false;
|
|
96
|
+
|
|
97
|
+
const {right} = props;
|
|
98
|
+
props.right = (props)=>{
|
|
99
|
+
const r = typeof right =='function'? right (props) : React.isValidElement(right)? right : null;
|
|
100
|
+
if(!defValue){
|
|
101
|
+
return <>{r}<ActivityIndicator
|
|
102
|
+
{...props}
|
|
103
|
+
style = {[props.style,{marginRight:10}]}
|
|
104
|
+
/></>
|
|
105
|
+
}
|
|
106
|
+
return r;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
this.setValidRule(props.validType);
|
|
110
|
+
} else {
|
|
111
|
+
props.enableCopy = false;
|
|
112
|
+
props.disabled = props.readOnly = false;
|
|
102
113
|
}
|
|
103
|
-
this.setValidRule(props.validType);
|
|
104
114
|
return super._render(props,setRef);
|
|
105
115
|
}
|
|
106
116
|
}
|
|
@@ -70,13 +70,19 @@ export const getFilterComponentProps = (_props)=>{
|
|
|
70
70
|
errorText,
|
|
71
71
|
label,text,
|
|
72
72
|
primary,
|
|
73
|
-
onValidate,
|
|
74
73
|
checkPiece,
|
|
75
74
|
check,
|
|
76
75
|
width,
|
|
77
76
|
type,
|
|
77
|
+
visible,
|
|
78
78
|
jsType,
|
|
79
79
|
filterType,
|
|
80
|
+
getValidValue,
|
|
81
|
+
validate,
|
|
82
|
+
onValidate,
|
|
83
|
+
onValidatorValid,///il s'agit de la fonction de rappel appelée immédiatement après que le validateur ait réuissie la validation
|
|
84
|
+
onValidateField,
|
|
85
|
+
onNoValidate,
|
|
80
86
|
...props
|
|
81
87
|
} = _props;
|
|
82
88
|
props = defaultObj(props);
|
|
@@ -86,13 +92,13 @@ export const getFilterComponentProps = (_props)=>{
|
|
|
86
92
|
const sanitizedType = type.replaceAll("_","").toLowerCase().trim();
|
|
87
93
|
props = defaultObj(props);
|
|
88
94
|
props.label = defaultStr(label,text);
|
|
89
|
-
if(
|
|
95
|
+
if(sanitizedType.startsWith("select")){
|
|
90
96
|
props.inputProps = Object.assign({},props.inputProps);
|
|
91
97
|
props.inputProps.placeholder = defaultStr(props.inputProps.placeholder,i18n.lang("search.."))
|
|
92
98
|
component = componentTypes.SelectField;
|
|
93
|
-
if(
|
|
99
|
+
if(sanitizedType ==='selectcountry'){
|
|
94
100
|
component = componentTypes.SelectCountry;
|
|
95
|
-
} else if(
|
|
101
|
+
} else if(sanitizedType ==='selecttabledata'){
|
|
96
102
|
component = componentTypes.SelectTableData;
|
|
97
103
|
} else if(React.isComponent(componentTypes[type])){
|
|
98
104
|
component = componentTypes[type];
|
|
@@ -133,6 +139,7 @@ export const getFilterComponentProps = (_props)=>{
|
|
|
133
139
|
props.multiple = true;
|
|
134
140
|
}
|
|
135
141
|
props.renderFilter = true;
|
|
142
|
+
props.isFilter = true;
|
|
136
143
|
if(type.contains("date") || type.contains("time")){
|
|
137
144
|
delete props.right;
|
|
138
145
|
}
|
|
@@ -3,7 +3,7 @@ import PropTypes from "prop-types";
|
|
|
3
3
|
import Tooltip from "$ecomponents/Tooltip";
|
|
4
4
|
import theme,{flattenStyle,Colors} from "$theme";
|
|
5
5
|
import React from "$react";
|
|
6
|
-
import {IconButton} from "react-native-paper"
|
|
6
|
+
import {IconButton} from "react-native-paper";
|
|
7
7
|
|
|
8
8
|
const IconComponentRef = React.forwardRef((props,ref)=>{
|
|
9
9
|
let {icon,style,Component,button,color,name,containerColor,...rest} = props;
|
|
@@ -58,8 +58,7 @@ const VirtuosoListComponent = React.forwardRef(({onRender,id,fixedHeaderContent,
|
|
|
58
58
|
const containerId = `${id}-container`;
|
|
59
59
|
const headId = `${id}-table-head`;
|
|
60
60
|
testID = defaultStr(testID,containerProps.testID,"RN_VirtuosoListComponent");
|
|
61
|
-
const
|
|
62
|
-
const listId = listIdRef.current;
|
|
61
|
+
const listId = `${id}-list`;
|
|
63
62
|
const listRef = React.useRef(null);
|
|
64
63
|
const sizeRef = React.useRef({width:0,height:0});
|
|
65
64
|
const listSize = sizeRef.current;
|
|
@@ -5,15 +5,19 @@ import { ActivityIndicator, Colors } from 'react-native-paper';
|
|
|
5
5
|
import theme,{defaultDarkTheme} from "$theme";
|
|
6
6
|
import {isIos} from "$cplatform";
|
|
7
7
|
import appConfig from "$capp/config";
|
|
8
|
+
import {defaultStr} from "$cutils";
|
|
8
9
|
|
|
9
|
-
export default function LogoProgress (
|
|
10
|
+
export default function LogoProgress ({testID}){
|
|
11
|
+
testID = defaultStr(testID,"RN_LogoProgress");
|
|
10
12
|
let containerStyle = {width:(Logo.width?Logo.width:undefined),height:(Logo.height?(Logo.height+100):undefined),flex:1,alignItems:"center",justifyContent:"center"};
|
|
11
13
|
const primaryColor = theme.colors.primaryOnSurface,
|
|
12
14
|
secondaryColor = theme.colors.secondaryOnSurface;
|
|
13
|
-
return <View style={[containerStyle]}>
|
|
14
|
-
<Logo key='logo' style={{marginBottom:0}} color={primaryColor}/>
|
|
15
|
-
<
|
|
16
|
-
|
|
15
|
+
return <View style={[containerStyle]} testID={testID+"_ProgressLogoContainer"}>
|
|
16
|
+
<Logo key='logo' style={{marginBottom:0}} color={primaryColor} testID={testID+"_ProgressLogo"}/>
|
|
17
|
+
<View style={{marginTop:20}} testID={testID+"_LogoProgressActivityIndicatorContainer"}>
|
|
18
|
+
<ActivityIndicator size = {isIos()?'large':40} animating={true} color={secondaryColor} />
|
|
19
|
+
</View>
|
|
20
|
+
<View key={'app-version'} style={{flex:1}} testID={testID+"_LogoProgressVersion"}>
|
|
17
21
|
<Label style={[{marginTop:10, fontWeight:'bold',color:secondaryColor}]}>version {appConfig.version}</Label>
|
|
18
22
|
</View>
|
|
19
23
|
</View>
|