@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.
Files changed (42) hide show
  1. package/package.json +2 -2
  2. package/src/components/Datagrid/Accordion/Filters.js +36 -38
  3. package/src/components/Datagrid/Common/Common.js +5 -2
  4. package/src/components/Datagrid/SWRDatagrid.js +22 -53
  5. package/src/components/Dialog/AppBarDialog.js +2 -1
  6. package/src/components/ErrorBoundary/ErrorMessage.js +3 -2
  7. package/src/components/ErrorBoundary/Provider.js +4 -3
  8. package/src/components/ErrorBoundary/index.js +1 -0
  9. package/src/components/Filter/index.js +1 -0
  10. package/src/components/Form/Fields/Field.js +3 -2
  11. package/src/components/Form/Fields/IdField.js +38 -28
  12. package/src/components/Form/FormData/componentsTypes.js +11 -4
  13. package/src/components/Icon/Icon.js +1 -1
  14. package/src/components/List/Virtuoso/index.js +1 -2
  15. package/src/components/Logo/Progress.js +9 -5
  16. package/src/components/Menu/Menu.js +113 -97
  17. package/src/components/Portal/Portal.js +88 -0
  18. package/src/components/Portal/PortalHost.js +31 -0
  19. package/src/components/Portal/PortalProvider.js +31 -0
  20. package/src/components/Portal/constants.js +15 -0
  21. package/src/components/Portal/context.js +10 -0
  22. package/src/components/Portal/hooks.js +75 -0
  23. package/src/components/Portal/index.js +11 -3
  24. package/src/components/Portal/index.old.js +4 -0
  25. package/src/components/Portal/reducer.js +92 -0
  26. package/src/components/Portal/usePortalState.js +19 -0
  27. package/src/components/Preloader/index.js +1 -1
  28. package/src/components/ScrollView/index.js +1 -0
  29. package/src/components/SplashScreen/index.js +2 -2
  30. package/src/components/StatusBar/Component/index.web.js +0 -1
  31. package/src/components/Table/EmptyPlaceholder/index.js +41 -0
  32. package/src/components/Table/EmptyPlaceholder/index.native.js +3 -0
  33. package/src/components/Table/hooks.js +1 -1
  34. package/src/components/Table/index.js +13 -7
  35. package/src/components/TextField/index.js +1 -0
  36. package/src/context/Provider.js +7 -0
  37. package/src/context/hooks.js +1 -2
  38. package/src/context/query.js +92 -0
  39. package/src/index.js +34 -41
  40. package/src/navigation/index.js +2 -1
  41. package/src/screens/Help/openLibraries.js +1 -1
  42. 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.2",
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.28.4",
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,getFilterStateValues} from "$ecomponents/Filter";
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 [state,setState] = React.useState({
24
- visible : defaultBool(customVisible,false),
25
- visibleColumns : defaultObj(filteredColumns),
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
- setState({...state,visibleColumns:{...visibleColumns,[key]:!visible}})
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
- <Filter
76
- {...filter}
77
- {...(isObj(valuesRefs.current[key]) ? valuesRefs.current[key] : {})}
78
- dynamicRendered
79
- //isLoading = {isLoading && filteredRef.current[key] ? true : false}
80
- orOperator = {defaultBool(orOperator,filter.orOperator,true)}
81
- andOperator = {defaultBool(andOperator,filter.andOperator,true)}
82
- onChange = {(arg)=>{
83
- if(!arg.action && !arg.operator || !arg.field) return;
84
- const canHandle = canHandleFilter(arg);
85
- valuesRefs.current[key] = arg;
86
- if(filteredRef.current[key] !== canHandle){
87
- if(canHandle){
88
- canHandlerFilterRef.current++;
89
- } else {
90
- canHandlerFilterRef.current = Math.max(0,canHandlerFilterRef.current-1);
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
- filteredRef.current[key] = canHandle;
94
- if(onChange){
95
- onChange(arg);
96
- }
97
- }}
98
- withBottomSheet
99
- containerProps = {{...containerProps}}
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
- setState({...state,visible:false})
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(React.areEquals(nextProps.data,this.props.data) || (stableHash(nextProps.data) === stableHash(this.props.data))) {
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 isLoadingRef = React.useRef(true);
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
- isFetchingRef.current = false;
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).then(fetchCB).finally(()=>{
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).then(fetchCB).finally(()=>{
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 isLoading = isLoadingRef.current && customIsLoading || false;
235
- /*React.useEffect(()=>{
236
- innerRef.current && innerRef.current.setIsLoading && innerRef.current.setIsLoading(isLoading);
237
- },[isLoading])*/
238
- React.useEffect(()=>{
239
- const cb = refreshCBRef.current;
240
- refreshCBRef.current = null;
241
- if(!isValidating && !customIsLoading && typeof cb =='function'){
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
- },[isValidating,customIsLoading])
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 totalRef.current !=='number' || typeof pageRef.current !='number' || typeof limitRef.current !='number') return false;
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(totalRef.current / limitRef.current);;
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 totalRef.current > limitRef.current && true || false;
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
- {(totalRef.current?page:0).formatNumber()}-{totalPages.formatNumber()}{" / "}{totalRef.current.formatNumber()}
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 = {dataRef.current}
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='RN_ErrorBoundary_Container' pointerEvents={pointerEvents} style={[styles.container,isWeb()?{position:'fixed'}:null,{backgroundColor:theme.colors.surface,width,height}]}>
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
  }}/>
@@ -38,6 +38,7 @@ class ErrorBoundary extends React.Component {
38
38
  } else {
39
39
  return (
40
40
  <ErrorMessage
41
+ testID={"RN_ErrorBoundaryErrorMessage"}
41
42
  error={error}
42
43
  info={info}
43
44
  resetError={this.resetError}
@@ -425,6 +425,7 @@ export default class Filter extends AppComponent {
425
425
  dynamicRendered,
426
426
  tooltipLabel,
427
427
  andOperator,
428
+ orOperator,
428
429
  searchIcon,
429
430
  field,
430
431
  style,
@@ -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
- const upper = props.upper !== false ? UPPER_CASE : "";
76
- if(isNonNullString(this.name) && isObj(props.data) && isNonNullString(props.data[this.name])){
77
- props.disabled = true;
78
- props.validType = upper;
79
- props.defaultValue = props.data[this.name];
80
- } else {
81
- props.validType = 'required|'+upper;
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
- return r;
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(type.startsWith("select")){
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(type =='select_country' || type =='selectcountry'){
99
+ if(sanitizedType ==='selectcountry'){
94
100
  component = componentTypes.SelectCountry;
95
- } else if(type =='select_tabledata' || type =='selecttabledata'){
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 listIdRef = React.useRef(uniqid("virtuoso-list-id"));
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 (props){
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
- <ActivityIndicator size = {isIos()?'large':40} animating={true} color={secondaryColor} />
16
- <View key={'app-version'} style={{flex:1}}>
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>