@fto-consult/expo-ui 2.5.0 → 2.5.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 +1 -1
- package/src/components/BottomSheet/Menu.js +4 -2
- package/src/components/Datagrid/Accordion/index.js +6 -5
- package/src/components/Datagrid/Common/Common.js +26 -11
- package/src/components/Datagrid/Footer/Footer.js +10 -12
- package/src/components/Datagrid/Table/index.js +29 -42
- package/src/components/Date/DatePickerInput/index.js +1 -1
- package/src/components/Date/DateTime.js +11 -6
- package/src/components/Date/Time.js +5 -1
- package/src/components/Dropdown/index.js +4 -5
- package/src/components/Filter/index.js +16 -8
- package/src/components/Table/AbsoluteScrollView.js +38 -10
- package/src/components/Table/index.js +74 -28
- package/src/components/TextField/index.js +2 -2
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@ import PropTypes from "prop-types";
|
|
|
8
8
|
import {getContentHeight} from "./utils";
|
|
9
9
|
|
|
10
10
|
const BottomSheetMenuComponent = React.forwardRef((props,ref)=>{
|
|
11
|
-
let {anchor,screenIndent,height:customHeight,bindResizeEvent,onDismiss,testID,visible:customVisible,controlled,mobile,animateOnClose,renderMenuContent,sheet,children,...rest} = props;
|
|
11
|
+
let {anchor,anchorProps,screenIndent,height:customHeight,bindResizeEvent,onDismiss,testID,visible:customVisible,controlled,mobile,animateOnClose,renderMenuContent,sheet,children,...rest} = props;
|
|
12
12
|
rest = defaultObj(rest);
|
|
13
13
|
const isControlled = controlled ? true : false;
|
|
14
14
|
const visibleRef = React.useRef(null);
|
|
@@ -44,12 +44,13 @@ const BottomSheetMenuComponent = React.forwardRef((props,ref)=>{
|
|
|
44
44
|
setState({...state,visible:false})
|
|
45
45
|
}
|
|
46
46
|
const Component = isMob ? BottomSheet : Menu;
|
|
47
|
+
anchorProps = defaultObj(anchorProps);
|
|
47
48
|
if(isMob){
|
|
48
49
|
if(typeof anchor ==='function'){
|
|
49
50
|
anchor = anchor(!isControlled?{onPress:open}:{});
|
|
50
51
|
}
|
|
51
52
|
if(React.isValidElement(anchor)){
|
|
52
|
-
anchor = <View testID={testID+"_Anchor"} ref={anchorRef} collapsable={false}>{anchor}</View>
|
|
53
|
+
anchor = <View testID={testID+"_Anchor"} ref={anchorRef} {...anchorProps} collapsable={false}>{anchor}</View>
|
|
53
54
|
}
|
|
54
55
|
if(renderMenuContent !== false){
|
|
55
56
|
children = renderItems({testID:testID+".Items",...props,closeMenu:close,openMenu:open,isBottomSheetItem:true});
|
|
@@ -101,6 +102,7 @@ const BottomSheetMenuComponent = React.forwardRef((props,ref)=>{
|
|
|
101
102
|
height = {controlled?customHeight:height}
|
|
102
103
|
ref = {React.useMergeRefs(innerRef,ref)}
|
|
103
104
|
anchor = {anchor}
|
|
105
|
+
anchorProps = {anchorProps}
|
|
104
106
|
children = {visible && (React.isValidElement(children) || Array.isArray(children))?children:undefined}
|
|
105
107
|
/>
|
|
106
108
|
</>
|
|
@@ -385,7 +385,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
385
385
|
if(toggleFilters === false){
|
|
386
386
|
filters = false;
|
|
387
387
|
}
|
|
388
|
-
let {showFilters,
|
|
388
|
+
let {showFilters,showFooters} = this.state;
|
|
389
389
|
let max = this.getMaxSelectableRows();
|
|
390
390
|
let restItems = [];
|
|
391
391
|
|
|
@@ -499,9 +499,9 @@ const DatagridFactory = (Factory)=>{
|
|
|
499
499
|
closeOnPress : false,
|
|
500
500
|
} : null,
|
|
501
501
|
hasFooterFields ? {
|
|
502
|
-
onPress : ()=>{
|
|
503
|
-
,icon :
|
|
504
|
-
,text : (
|
|
502
|
+
onPress : ()=>{showFooters?this.hideFooter():this.showFooters()}
|
|
503
|
+
,icon : showFooters?'view-column':'view-module'
|
|
504
|
+
,text : (showFooters?'Masquer/Ligne des totaux':'Afficher/Ligne des totaux')
|
|
505
505
|
}:null,
|
|
506
506
|
...restItems,
|
|
507
507
|
this.canScrollTo() && {
|
|
@@ -557,7 +557,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
557
557
|
/>
|
|
558
558
|
{datagridHeader}
|
|
559
559
|
{_progressBar}
|
|
560
|
-
{
|
|
560
|
+
{showFooters ? (
|
|
561
561
|
<View testID={testID+"_FooterContainer"} pointerEvents={pointerEvents} style={[{justifyContent:'center'}]}>
|
|
562
562
|
<View testID={testID+"_FooterContentContainer"} style={[styles.footersContainer]}>
|
|
563
563
|
<ScrollView testID={testID+"_FooterScrollView"} horizontal contentContainerStyle={[styles.contentContainerStyle]}>
|
|
@@ -567,6 +567,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
567
567
|
key = {field}
|
|
568
568
|
testID={testID+"_FooterItem_"+field}
|
|
569
569
|
{...footer}
|
|
570
|
+
anchorProps = {{style:[theme.styles.ph1,theme.styles.mh05]}}
|
|
570
571
|
/>
|
|
571
572
|
})}
|
|
572
573
|
</View>
|
|
@@ -71,13 +71,13 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
71
71
|
});
|
|
72
72
|
selectedRows = sRows;
|
|
73
73
|
let sData = this.getSessionData()
|
|
74
|
-
sData.
|
|
74
|
+
sData.showFooters = defaultVal(sData.showFooters,true);
|
|
75
75
|
sData.fixedTable = defaultBool(sData.fixedTable,false);
|
|
76
76
|
extendObj(this.state, {
|
|
77
77
|
data,
|
|
78
78
|
sort :defaultObj(props.sort),
|
|
79
79
|
showFilters : defaultBool(props.showFilters,(sData.showFilter? true : this.isPivotDatagrid())),
|
|
80
|
-
|
|
80
|
+
showFooters : defaultBool(props.showFooters,(sData.showFooters? true : false)),
|
|
81
81
|
fixedTable : sData.fixedTable
|
|
82
82
|
});
|
|
83
83
|
Object.defineProperties(this,{
|
|
@@ -784,16 +784,16 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
784
784
|
}
|
|
785
785
|
|
|
786
786
|
|
|
787
|
-
|
|
787
|
+
showFooters(){
|
|
788
788
|
if(!this._isMounted()) {
|
|
789
789
|
this.isUpdating = false;
|
|
790
790
|
return;
|
|
791
791
|
}
|
|
792
792
|
if(this.isUpdating) return false;
|
|
793
793
|
this.isUpdating = true;
|
|
794
|
-
this.setState( {
|
|
794
|
+
this.setState( {showFooters:true},()=>{
|
|
795
795
|
this.isUpdating = false;
|
|
796
|
-
this.setSessionData({
|
|
796
|
+
this.setSessionData({showFooters:true})
|
|
797
797
|
})
|
|
798
798
|
}
|
|
799
799
|
hideFooter (){
|
|
@@ -802,9 +802,9 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
802
802
|
return;
|
|
803
803
|
}
|
|
804
804
|
if(this.isUpdating) return false;
|
|
805
|
-
this.setState({
|
|
805
|
+
this.setState({showFooters:false},()=>{
|
|
806
806
|
this.isUpdating = false;
|
|
807
|
-
this.setSessionData({
|
|
807
|
+
this.setSessionData({showFooters:false});
|
|
808
808
|
})
|
|
809
809
|
}
|
|
810
810
|
|
|
@@ -899,14 +899,18 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
899
899
|
let colFilter = defaultVal(restCol.filter,true);
|
|
900
900
|
field = header.field = defaultStr(header.field,field,headerIndex);
|
|
901
901
|
delete restCol.filter;
|
|
902
|
+
|
|
903
|
+
const type = defaultStr(header.type).toLowerCase();
|
|
904
|
+
sortType = defaultStr(sortType,type).toLowerCase();
|
|
902
905
|
width = defaultDecimal(width);
|
|
903
906
|
if(width <COLUMN_WIDTH/2){
|
|
904
907
|
width = COLUMN_WIDTH;
|
|
905
908
|
}
|
|
906
|
-
const type = defaultStr(header.type).toLowerCase();
|
|
907
|
-
sortType = defaultStr(sortType,type).toLowerCase();
|
|
908
909
|
if(type.contains("date")|| type.contains("time")){
|
|
909
|
-
|
|
910
|
+
const mWidth = type.toLowerCase().contains('datetime')? (DATE_COLUMN_WIDTH+30) : DATE_COLUMN_WIDTH;
|
|
911
|
+
width = Math.max(width,mWidth);
|
|
912
|
+
} else if((type.contains("number") || type.contains("decimal") && this.props.format)){
|
|
913
|
+
width = Math.max(width,DATE_COLUMN_WIDTH-30);
|
|
910
914
|
}
|
|
911
915
|
totalWidths +=width;
|
|
912
916
|
widths[header.field] = width;
|
|
@@ -953,6 +957,17 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
953
957
|
delete restCol.sortable;
|
|
954
958
|
filterProps = {
|
|
955
959
|
...restCol,
|
|
960
|
+
columnIndex,
|
|
961
|
+
visibleColumnIndex,
|
|
962
|
+
sortable:isColumnSortable,
|
|
963
|
+
sorted:isColumnSorted,
|
|
964
|
+
sortedColumn :sortedProps,///les props de la columns triée
|
|
965
|
+
sortedProps,
|
|
966
|
+
width,
|
|
967
|
+
columnField : field,
|
|
968
|
+
columnDef : header,
|
|
969
|
+
index : headerIndex,
|
|
970
|
+
visible,
|
|
956
971
|
key : header.field,
|
|
957
972
|
label : defaultStr(header.label,header.text),
|
|
958
973
|
orOperator : filterOrOperator,
|
|
@@ -1710,7 +1725,7 @@ CommonDatagridComponent.propTypes = {
|
|
|
1710
1725
|
/*** affiche ou masque les filtres */
|
|
1711
1726
|
showFilters : PropTypes.bool,
|
|
1712
1727
|
/*** si le pied de page sera affiché */
|
|
1713
|
-
|
|
1728
|
+
showFooters : PropTypes.bool,
|
|
1714
1729
|
/*** les donnnées peuvent être soient retournées par une fonction, soit par un tableau soit une promesse */
|
|
1715
1730
|
data : PropTypes.oneOfType([PropTypes.array, PropTypes.func,PropTypes.object]),//.isRequired,
|
|
1716
1731
|
columns:PropTypes.oneOfType([PropTypes.array,PropTypes.object]),//.isRequired,
|
|
@@ -3,7 +3,7 @@ import Menu from "$ecomponents/BottomSheet/Menu";
|
|
|
3
3
|
import View from "$ecomponents/View";
|
|
4
4
|
import {Pressable,StyleSheet} from "react-native";
|
|
5
5
|
import Label from "$ecomponents/Label";
|
|
6
|
-
import {defaultVal} from "$utils";
|
|
6
|
+
import {defaultVal,defaultObj} from "$utils";
|
|
7
7
|
import React from "$react";
|
|
8
8
|
import theme from "$theme"
|
|
9
9
|
|
|
@@ -18,7 +18,9 @@ const formatValue = ({value,format,method})=>{
|
|
|
18
18
|
return (format === 'money' && method != 'count')? value.formatMoney():value.formatNumber();
|
|
19
19
|
}
|
|
20
20
|
export default function DGGridFooterValue (props){
|
|
21
|
-
let {label,text,displayLabel,style,format} = props;
|
|
21
|
+
let {label,text,displayLabel,style,format,testID,anchorProps} = props;
|
|
22
|
+
anchorProps = defaultObj(anchorProps);
|
|
23
|
+
testID = defaultStr(testID,"RN_DatagridFooterComponent");
|
|
22
24
|
label = defaultVal(label,text);
|
|
23
25
|
const defLabel = label;
|
|
24
26
|
if(displayLabel !== false){
|
|
@@ -50,19 +52,19 @@ export default function DGGridFooterValue (props){
|
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
54
|
return <Menu
|
|
55
|
+
testID = {testID+"_Menu"}
|
|
53
56
|
items = {menuItems}
|
|
54
|
-
style = {{minWidth:220}}
|
|
55
57
|
title = {'Totaux de la colonne '+(defLabel?("[ "+defLabel+"]"):'')}
|
|
56
58
|
animateOnClose
|
|
57
59
|
anchor = {(p)=>{
|
|
58
|
-
return <Pressable {...p} style={[styles.anchor,style,label?styles.row:null]} title={title}>
|
|
60
|
+
return <Pressable {...anchorProps} {...p} testID={testID} style={[styles.anchor,anchorProps.style,label?styles.row:null]} title={title}>
|
|
59
61
|
{label ?
|
|
60
62
|
<>
|
|
61
|
-
<View><Label style={[styles.label]}>{label}</Label></View>
|
|
62
|
-
<View><Label style = {styles.label}> : </Label></View>
|
|
63
|
+
<View testID={testID+"_Label"}><Label style={[styles.label]}>{label}</Label></View>
|
|
64
|
+
<View testID={testID+"_LabelPoint"}><Label style = {styles.label}> : </Label></View>
|
|
63
65
|
</>
|
|
64
66
|
: null}
|
|
65
|
-
<Label primary style={[styles.value]}>
|
|
67
|
+
<Label testID={testID+"_LabelContent"} primary style={[styles.value]}>
|
|
66
68
|
{formatValue({value:defaultDecimal(props[active]),method:active,format})}
|
|
67
69
|
</Label>
|
|
68
70
|
</Pressable>
|
|
@@ -75,11 +77,7 @@ const styles = StyleSheet.create({
|
|
|
75
77
|
flexDirection : 'row',
|
|
76
78
|
alignItems : 'center',
|
|
77
79
|
},
|
|
78
|
-
anchor : {
|
|
79
|
-
paddingVertical : 10,
|
|
80
|
-
marginHorizontal : 10,
|
|
81
|
-
paddingHorizontal : 5,
|
|
82
|
-
},
|
|
80
|
+
anchor : {},
|
|
83
81
|
value : {
|
|
84
82
|
fontWeight : 'bold'
|
|
85
83
|
}
|
|
@@ -13,6 +13,7 @@ import React from "$react";
|
|
|
13
13
|
import {Menu as BottomSheetMenu} from "$ecomponents/BottomSheet"
|
|
14
14
|
import RenderType from "../RenderType";
|
|
15
15
|
import Footer from "../Footer/Footer";
|
|
16
|
+
import theme from "$theme";
|
|
16
17
|
import Table from "$ecomponents/Table";
|
|
17
18
|
|
|
18
19
|
|
|
@@ -62,41 +63,23 @@ const DatagridFactory = (Factory)=>{
|
|
|
62
63
|
}
|
|
63
64
|
return null;
|
|
64
65
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
if(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}}
|
|
81
|
-
/>
|
|
82
|
-
</View>
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return ret;
|
|
86
|
-
}
|
|
87
|
-
beforePrepareColumns(){
|
|
88
|
-
this.customFilteredColumns = {};
|
|
89
|
-
}
|
|
90
|
-
prepareColumn({filterProps,columnField,columnDef,key,field,visible,filter},filters){
|
|
91
|
-
this.customFilteredColumns = defaultObj(this.customFilteredColumns);
|
|
92
|
-
if(visible){
|
|
93
|
-
if(filter){
|
|
94
|
-
this.customFilteredColumns[columnField] = filterProps;
|
|
95
|
-
} else {
|
|
96
|
-
this.customFilteredColumns[columnField] = null;
|
|
97
|
-
}
|
|
66
|
+
renderFilterCell(props){
|
|
67
|
+
const {columnField,style} = props;
|
|
68
|
+
const filterC = this.currentFilteringColumns[columnField];
|
|
69
|
+
if(isObj(filterC)){
|
|
70
|
+
return <Filter
|
|
71
|
+
{...filterC}
|
|
72
|
+
withLabel = {false}
|
|
73
|
+
style = {[styles.filter,theme.styles.pv0,theme.styles.mv0]}
|
|
74
|
+
anchorProps ={{size:20}}
|
|
75
|
+
mode = "flat"
|
|
76
|
+
inputProps = {{
|
|
77
|
+
style : [styles.filter],
|
|
78
|
+
mode : "flat",
|
|
79
|
+
}}
|
|
80
|
+
/>
|
|
98
81
|
}
|
|
99
|
-
return
|
|
82
|
+
return null;
|
|
100
83
|
}
|
|
101
84
|
updateLayout(e){
|
|
102
85
|
if(this.state.fixedTable === false) return;
|
|
@@ -176,7 +159,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
176
159
|
})*/
|
|
177
160
|
const {visibleColumns} = this.preparedColumns;
|
|
178
161
|
const hasFooterFields = this.hasFooterFields();
|
|
179
|
-
const {columnsWidths:widths,showFilters,
|
|
162
|
+
const {columnsWidths:widths,showFilters,showFooters} = this.state;
|
|
180
163
|
let isAllRowsSelected = this.isAllRowsSelected();
|
|
181
164
|
const isLoading = this.isLoading();
|
|
182
165
|
let _progressBar = this.getProgressBar();
|
|
@@ -227,10 +210,10 @@ const DatagridFactory = (Factory)=>{
|
|
|
227
210
|
{hasFooterFields ? <Button
|
|
228
211
|
normal
|
|
229
212
|
style={styles.paginationItem}
|
|
230
|
-
onPress = {()=>{
|
|
231
|
-
icon = {
|
|
213
|
+
onPress = {()=>{showFooters?this.hideFooter():this.showFooters()} }
|
|
214
|
+
icon = {showFooters?'view-column':'view-module'}
|
|
232
215
|
>
|
|
233
|
-
{
|
|
216
|
+
{showFooters?'Masquer/Ligne des totaux':'Afficher/Ligne des totaux'}
|
|
234
217
|
</Button>:null}
|
|
235
218
|
{selectableMultiple && (<>
|
|
236
219
|
{restItems.map((item,index)=>{
|
|
@@ -287,9 +270,9 @@ const DatagridFactory = (Factory)=>{
|
|
|
287
270
|
,text : (showFilters?'Masquer/Filtres':'Afficher/Filtres')
|
|
288
271
|
} : null,
|
|
289
272
|
isMobile && hasFooterFields?{
|
|
290
|
-
onPress : ()=>{
|
|
291
|
-
,icon :
|
|
292
|
-
,text : (
|
|
273
|
+
onPress : ()=>{showFooters?this.hideFooter():this.showFooters()}
|
|
274
|
+
,icon : showFooters?'view-column':'view-module'
|
|
275
|
+
,text : (showFooters?'Masquer/Ligne des totaux':'Afficher/Ligne des totaux')
|
|
293
276
|
} : null,
|
|
294
277
|
...(selectableMultiple ? restItems : [])
|
|
295
278
|
] : visibleColumns}
|
|
@@ -340,7 +323,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
340
323
|
ref = {this.listRef}
|
|
341
324
|
hasFooters = {hasFooterFields}
|
|
342
325
|
showFilters = {showFilters}
|
|
343
|
-
showFooters = {
|
|
326
|
+
showFooters = {showFooters}
|
|
344
327
|
headerContainerProps = {{}}
|
|
345
328
|
headerCellContainerProps = {{
|
|
346
329
|
style : showFilters?{justifyContent:'flex-start'}:null
|
|
@@ -358,7 +341,9 @@ const DatagridFactory = (Factory)=>{
|
|
|
358
341
|
}}
|
|
359
342
|
data = {this.state.data}
|
|
360
343
|
renderHeaderCell={this.renderHeaderCell.bind(this)}
|
|
344
|
+
renderFilterCell={this.renderFilterCell.bind(this)}
|
|
361
345
|
renderFooterCell={this.renderFooterCell.bind(this)}
|
|
346
|
+
renderEmpty = {this.renderEmpty.bind(this)}
|
|
362
347
|
/>
|
|
363
348
|
</View>
|
|
364
349
|
}
|
|
@@ -440,8 +425,10 @@ const styles = StyleSheet.create({
|
|
|
440
425
|
maxHeight : 40,
|
|
441
426
|
height : 40,
|
|
442
427
|
width : "100%",
|
|
428
|
+
alignSelf : 'flex-start',
|
|
443
429
|
flexGrow : 1,
|
|
444
430
|
minHeight : 40,
|
|
431
|
+
backgroundColor : 'transparent'
|
|
445
432
|
},
|
|
446
433
|
layoutContent : {
|
|
447
434
|
maxWidth : '100%',
|
|
@@ -166,7 +166,7 @@ const DatePickerInput = React.forwardRef(({
|
|
|
166
166
|
onChange({dateObject:state.inputDate,date:state.inputDate,sqlDate:date,value:date})
|
|
167
167
|
}
|
|
168
168
|
},[state])
|
|
169
|
-
const labelText = render_filter ? label :
|
|
169
|
+
const labelText = withLabel === false ? null: (render_filter ? label : getLabel({ label, inputFormat:inputFormatLabel, withDateFormatInLabel }));
|
|
170
170
|
return (
|
|
171
171
|
<>
|
|
172
172
|
<TextField
|
|
@@ -13,7 +13,7 @@ import { toDateObj } from "./utils";
|
|
|
13
13
|
import TextField from "$components/TextField";
|
|
14
14
|
import PeriodActionComponent from "./PeriodAction";
|
|
15
15
|
|
|
16
|
-
export default function DateTimePickerComponent({left,isPeriodAction,withSeconds,right,format,dateFormat,timeFormat,defaultValue,onChange,testID,dateProps,disabled,readOnly,timeProps,...rest}){
|
|
16
|
+
export default function DateTimePickerComponent({left,isPeriodAction,contentProps,withSeconds,right,format,dateFormat,timeFormat,defaultValue,onChange,testID,dateProps,disabled,readOnly,timeProps,...rest}){
|
|
17
17
|
if(!isPeriodAction){
|
|
18
18
|
isPeriodAction = isNonNullString(defaultValue) && defaultValue.contains("=>");
|
|
19
19
|
}
|
|
@@ -28,6 +28,7 @@ export default function DateTimePickerComponent({left,isPeriodAction,withSeconds
|
|
|
28
28
|
}
|
|
29
29
|
dateProps = defaultObj(dateProps);
|
|
30
30
|
timeProps = defaultObj(timeProps);
|
|
31
|
+
contentProps = defaultObj(contentProps);
|
|
31
32
|
testID = defaultStr(testID,"RN_DateTimeComponent")
|
|
32
33
|
const anchorTimeProps = defaultObj(timeProps.anchorProps);
|
|
33
34
|
const timePropsContainerProps = defaultObj(timeProps.containerProps);
|
|
@@ -52,8 +53,8 @@ export default function DateTimePickerComponent({left,isPeriodAction,withSeconds
|
|
|
52
53
|
const timeDefaultValue = getTimeValue(dateObj);
|
|
53
54
|
const changedTimeArgsRef = {current:{...defaultObj(parseTime(timeDefaultValue,withSeconds))}};
|
|
54
55
|
withSeconds = defaultBool(timeProps.withSeconds,withSeconds,true);
|
|
55
|
-
|
|
56
|
-
const maxWidth =
|
|
56
|
+
const cStyle = [theme.styles.noPadding,theme.styles.noMargin];
|
|
57
|
+
const maxWidth = 110;
|
|
57
58
|
const callOnChange = ()=>{
|
|
58
59
|
if(onChange){
|
|
59
60
|
const dObj = changeDateArgsRef.current;
|
|
@@ -71,6 +72,8 @@ export default function DateTimePickerComponent({left,isPeriodAction,withSeconds
|
|
|
71
72
|
onChange(args);
|
|
72
73
|
}
|
|
73
74
|
}
|
|
75
|
+
const tInputProps = defaultObj(timeProps.inputProps);
|
|
76
|
+
const dStyle = flattenStyle([rest.style,dateProps.style]);
|
|
74
77
|
return <DateComponent
|
|
75
78
|
defaultValue = {dateObj}
|
|
76
79
|
disabled = {disabled}
|
|
@@ -79,7 +82,7 @@ export default function DateTimePickerComponent({left,isPeriodAction,withSeconds
|
|
|
79
82
|
{...rest}
|
|
80
83
|
format = {dateFormat}
|
|
81
84
|
{...dateProps}
|
|
82
|
-
style = {
|
|
85
|
+
style = {dStyle}
|
|
83
86
|
calendarIconBefore = {true}
|
|
84
87
|
onChange = {(args)=>{
|
|
85
88
|
changeDateArgsRef.current = args;
|
|
@@ -102,15 +105,17 @@ export default function DateTimePickerComponent({left,isPeriodAction,withSeconds
|
|
|
102
105
|
}}
|
|
103
106
|
withLabel = {false}
|
|
104
107
|
mode = {"flat"}
|
|
105
|
-
|
|
108
|
+
contentProps = {{style:cStyle}}
|
|
109
|
+
containerProps = {{...timePropsContainerProps,style:[{maxWidth},theme.styles.noPadding,theme.styles.noMargin,timePropsContainerProps.style]}}
|
|
106
110
|
divider = {false}
|
|
111
|
+
style = {[theme.styles.noPadding,{maxHeight:40},theme.styles.noMargin,timeProps.style,dStyle.backgroundColor && {backgroundColor:dStyle.backgroundColor}]}
|
|
107
112
|
anchorProps = {{
|
|
108
113
|
...anchorTimeProps,
|
|
109
114
|
testID:testID+"_TimeAnchor",
|
|
110
115
|
style : [theme.styles.noPadding,{borderRadius:0},theme.styles.noMargin,anchorTimeProps.style]
|
|
111
116
|
}}
|
|
112
117
|
inputProps = {{
|
|
113
|
-
...
|
|
118
|
+
...tInputProps,
|
|
114
119
|
mode : "flat",
|
|
115
120
|
}}
|
|
116
121
|
/>
|
|
@@ -44,8 +44,9 @@ export const timeToString = (value,withSeconds)=>{
|
|
|
44
44
|
return value.substring(0,5);
|
|
45
45
|
}
|
|
46
46
|
export default function TimePickerComponent (props){
|
|
47
|
-
let {right:customRight,upper,anchorProps,dialogProps,withLabel,containerProps,mode,onChange,withSeconds,cancelLabel,confirmLabel,label,text,upperCase,defaultValue,disabled,editable,withModal,readOnly,...rest} = props;
|
|
47
|
+
let {right:customRight,upper,anchorProps,dialogProps,withLabel,inputProps,containerProps,mode,onChange,withSeconds,cancelLabel,confirmLabel,label,text,upperCase,defaultValue,disabled,editable,withModal,readOnly,...rest} = props;
|
|
48
48
|
rest = defaultObj(rest);
|
|
49
|
+
inputProps = defaultObj(inputProps);
|
|
49
50
|
const isEditable = disabled !== true && readOnly !== true && editable !== false?true : false;
|
|
50
51
|
withModal = defaultBool(withModal,true);
|
|
51
52
|
if(!isEditable){
|
|
@@ -110,6 +111,7 @@ export default function TimePickerComponent (props){
|
|
|
110
111
|
if(!disabled){
|
|
111
112
|
containerProps.style = [containerProps.style,{opacity:1}]
|
|
112
113
|
}
|
|
114
|
+
const iContainerProps = defaultObj(inputProps.containerProps);
|
|
113
115
|
return <>
|
|
114
116
|
<TouchableRipple {...containerProps}
|
|
115
117
|
disabled = {!isEditable}
|
|
@@ -120,6 +122,8 @@ export default function TimePickerComponent (props){
|
|
|
120
122
|
<TextField
|
|
121
123
|
mode = {mode||theme.textFieldMode}
|
|
122
124
|
{...rest}
|
|
125
|
+
{...inputProps}
|
|
126
|
+
containerProps = {{...iContainerProps,style:[containerProps.style,iContainerProps.style]}}
|
|
123
127
|
label = {label}
|
|
124
128
|
right = {right}
|
|
125
129
|
disabled = {disabled}
|
|
@@ -745,9 +745,10 @@ class DropdownComponent extends AppComponent {
|
|
|
745
745
|
const inputRest = {disabled,editable,label,error}
|
|
746
746
|
clearTimeout(this.doSearchFilter);
|
|
747
747
|
this.doSearchFilter = null;
|
|
748
|
-
|
|
748
|
+
mode = defaultStr(mode,inputProps.mode);
|
|
749
749
|
const textInputProps = {
|
|
750
750
|
...inputRest,
|
|
751
|
+
mode,
|
|
751
752
|
editable,disabled,
|
|
752
753
|
style : StyleSheet.flatten([styles.input,inputProps.style])
|
|
753
754
|
}
|
|
@@ -840,8 +841,7 @@ class DropdownComponent extends AppComponent {
|
|
|
840
841
|
}
|
|
841
842
|
helperText = <HelperText disabled = {disabled} error={error}>{helperText}</HelperText>
|
|
842
843
|
let labelTextField = defaultVal(label,text);
|
|
843
|
-
|
|
844
|
-
const isFlatMode = textInputProps.mode === flatMode;
|
|
844
|
+
const isFlatMode = textInputProps.mode === flatMode;
|
|
845
845
|
let backgroundColor = Colors.isValid(textInputProps.style.backgroundColor)?textInputProps.style.backgroundColor : Colors.isValid(flattenStyle.backgroundColor)? flattenStyle.backgroundColor : theme.colors.surface;
|
|
846
846
|
const tagLabelStyle = {backgroundColor,color:Colors.setAlpha(theme.colors.text,theme.ALPHA)}
|
|
847
847
|
if(!isFlatMode && backgroundColor ==='transparent'){
|
|
@@ -904,9 +904,9 @@ class DropdownComponent extends AppComponent {
|
|
|
904
904
|
defaultValue={selectedText}
|
|
905
905
|
autoHeight = {renderTag}
|
|
906
906
|
useReadOnlyOpacity = {false}
|
|
907
|
-
mode = {mode}
|
|
908
907
|
{...inputProps}
|
|
909
908
|
{...textInputProps}
|
|
909
|
+
mode = {mode}
|
|
910
910
|
enableCopy = {enableCopy}
|
|
911
911
|
label = {labelTextField}
|
|
912
912
|
pointerEvents = "none"
|
|
@@ -1270,7 +1270,6 @@ DropdownComponent.propTypes = {
|
|
|
1270
1270
|
onUnmount : PropTypes.func,
|
|
1271
1271
|
label : PropTypes.string,
|
|
1272
1272
|
placeholder : PropTypes.string,
|
|
1273
|
-
mode : PropTypes.oneOf(["outlined", "flat"]),
|
|
1274
1273
|
inputProps : PropTypes.object,
|
|
1275
1274
|
selectedColor:PropTypes.string,
|
|
1276
1275
|
accessibilityLabel : PropTypes.string,
|
|
@@ -24,6 +24,7 @@ export * from "./utils";
|
|
|
24
24
|
|
|
25
25
|
const _actions = {
|
|
26
26
|
'$eq' : 'Egal à',
|
|
27
|
+
"$ne" : 'Défférent de',
|
|
27
28
|
'$gt' : 'Supérieur à',
|
|
28
29
|
'$gte' : 'Supérieur ou égal',
|
|
29
30
|
'$lt' : 'Inférieur à',
|
|
@@ -135,6 +136,10 @@ export default class Filter extends AppComponent {
|
|
|
135
136
|
this.props.onValidate({...this.getStateValues(),field:this.props.name,...arg})
|
|
136
137
|
}
|
|
137
138
|
}
|
|
139
|
+
isDecimal(){
|
|
140
|
+
const t = defaultStr(this.type,this.props.type).toLowerCase();
|
|
141
|
+
return t =="number" || t =='decimal' ? true : false;
|
|
142
|
+
}
|
|
138
143
|
onFilterValidate(arg){
|
|
139
144
|
arg = defaultObj(arg);
|
|
140
145
|
if(JSON.stringify(this.state.defaultValue) === JSON.stringify(arg.value)){
|
|
@@ -190,11 +195,15 @@ export default class Filter extends AppComponent {
|
|
|
190
195
|
value = undefined;
|
|
191
196
|
}
|
|
192
197
|
let originValue = value;
|
|
193
|
-
const type = defaultStr(this.props.type).toLowerCase().trim();
|
|
194
|
-
value = parseDecimal(value,type);
|
|
195
198
|
if(action =="$today" || action =='$yesterday'){
|
|
196
199
|
force = true;
|
|
197
200
|
}
|
|
201
|
+
if(this.isDecimal()){
|
|
202
|
+
value = parseDecimal(value)
|
|
203
|
+
if(value == 0){
|
|
204
|
+
value = undefined;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
198
207
|
const prev = JSON.stringify(defaultObj(this.previousRef.current)), current = {value,operator,action,ignoreCase};
|
|
199
208
|
let tV = isArray(value) && value.length <= 0 ? undefined : value;
|
|
200
209
|
this.isInitializedRef.current = this.props.dynamicRendered || this.isInitializedRef.current;
|
|
@@ -290,8 +299,7 @@ export default class Filter extends AppComponent {
|
|
|
290
299
|
if(data.start && data.end && data.start> data.end){
|
|
291
300
|
return notify.error("La date de fin doit être supérieure à la date de début");
|
|
292
301
|
}
|
|
293
|
-
|
|
294
|
-
if(isFunction(success)){
|
|
302
|
+
if(isFunction(success)){
|
|
295
303
|
success(data.start+"=>"+data.end);
|
|
296
304
|
}
|
|
297
305
|
DialogProvider.close();
|
|
@@ -325,7 +333,6 @@ export default class Filter extends AppComponent {
|
|
|
325
333
|
break;
|
|
326
334
|
case "$week":
|
|
327
335
|
diff = DateLib.currentWeekDaysLimits(currentDate);
|
|
328
|
-
console.log(diff," is diffffff");
|
|
329
336
|
break;
|
|
330
337
|
case "$prevWeek":
|
|
331
338
|
diff = DateLib.previousWeekDaysLimits(currentDate)
|
|
@@ -383,8 +390,8 @@ export default class Filter extends AppComponent {
|
|
|
383
390
|
field,
|
|
384
391
|
style,
|
|
385
392
|
anchorProps,
|
|
386
|
-
mode,
|
|
387
|
-
inputProps,
|
|
393
|
+
//mode,
|
|
394
|
+
//inputProps,
|
|
388
395
|
moreOptions,
|
|
389
396
|
isLoading,
|
|
390
397
|
searchIconTooltip,
|
|
@@ -472,6 +479,7 @@ export default class Filter extends AppComponent {
|
|
|
472
479
|
}
|
|
473
480
|
anchorProps = defaultObj(anchorProps);
|
|
474
481
|
rest.anchorProps = anchorProps;
|
|
482
|
+
rest.withLabel = withLabel;
|
|
475
483
|
rest.pointerEvents = "auto";
|
|
476
484
|
rest.right = isLoading ? <ActivityIndicator color={theme.colors.secondaryOnSurface} animating/> :<>
|
|
477
485
|
<Menu
|
|
@@ -557,7 +565,7 @@ export default class Filter extends AppComponent {
|
|
|
557
565
|
if(ignoreDefaultValue) {
|
|
558
566
|
rest.isPeriodAction = true;
|
|
559
567
|
}
|
|
560
|
-
return <View testID={testID+"_FilterContainer"} {...containerProps} style={[theme.styles.w100,containerProps.style]}>
|
|
568
|
+
return <View testID={testID+"_FilterContainer"} {...containerProps} style={StyleSheet.flatten([theme.styles.w100,containerProps.style])}>
|
|
561
569
|
<Component
|
|
562
570
|
{...rest}
|
|
563
571
|
readOnly = {ignoreDefaultValue}
|
|
@@ -4,31 +4,59 @@
|
|
|
4
4
|
|
|
5
5
|
import { ScrollView,StyleSheet,View,useWindowDimensions} from "react-native";
|
|
6
6
|
import React from "$react";
|
|
7
|
-
import {defaultStr,defaultObj,isObj} from "$utils";
|
|
7
|
+
import {defaultStr,defaultObj,isObj,isNumber} from "$utils";
|
|
8
8
|
import Portal from "$ecomponents/Portal";
|
|
9
|
+
import {isMobileNative,isTouchDevice} from "$platform";
|
|
9
10
|
|
|
10
|
-
const
|
|
11
|
+
const isNative = isMobileNative() || isTouchDevice();
|
|
12
|
+
const AbsoluteScrollView = React.forwardRef(({testID,contentProps,listRef,containerProps,...props},ref)=>{
|
|
13
|
+
if(isNative) return null;
|
|
11
14
|
containerProps = defaultObj(containerProps);
|
|
12
15
|
contentProps = defaultObj(contentProps);
|
|
13
16
|
const win = useWindowDimensions();
|
|
14
17
|
const scrollViewRef = React.useRef(null);
|
|
15
18
|
testID = defaultStr(testID,"RN_TableAbsoluteScrollViewComponent");
|
|
16
|
-
const [
|
|
19
|
+
const [state,setState] = React.useState({
|
|
20
|
+
styles : {},
|
|
21
|
+
visible : true,
|
|
22
|
+
})
|
|
23
|
+
const {styles,visible} = state,setStyles = (s)=>{
|
|
24
|
+
if(isObj(s)){
|
|
25
|
+
setState({...state,styles:{...styles,...s}});
|
|
26
|
+
}
|
|
27
|
+
},toggleVisible = ()=>{
|
|
28
|
+
if(isObj(styles.content) && isObj(styles.container)){
|
|
29
|
+
const visible = isNumber(styles.content.height) && isNumber(styles.container.height) && (styles.content.height-20)> styles.container.height? true : false;
|
|
30
|
+
if(visible != state.visible){
|
|
31
|
+
setState({...state,visible});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
17
35
|
React.setRef(ref,{
|
|
18
|
-
setStyles
|
|
19
|
-
|
|
20
|
-
|
|
36
|
+
setStyles,
|
|
37
|
+
checkVisibility : (args)=>{
|
|
38
|
+
args = defaultObj(args);
|
|
39
|
+
if(isObj(args.contentOffset) && isObj(args.contentSize)){
|
|
40
|
+
const {x} = args.contentOffset;
|
|
41
|
+
const visible = x >=win.width ? false : true;
|
|
42
|
+
if(state.visible != visible){
|
|
43
|
+
return setState({...state,visible});
|
|
44
|
+
}
|
|
21
45
|
}
|
|
46
|
+
return toggleVisible();
|
|
22
47
|
},
|
|
23
48
|
scrollViewRef
|
|
24
|
-
})
|
|
49
|
+
});
|
|
25
50
|
React.useEffect(()=>{
|
|
26
51
|
return ()=>{
|
|
27
52
|
React.setRef(ref,null);
|
|
28
53
|
}
|
|
29
|
-
},[])
|
|
54
|
+
},[]);
|
|
55
|
+
React.useEffect(()=>{
|
|
56
|
+
toggleVisible();
|
|
57
|
+
},[styles])
|
|
30
58
|
return <Portal>
|
|
31
|
-
<View testID={testID+"_Containter"} {...containerProps} style={[mainStyles.container,containerProps.style,styles.container,{left:win.width-10}]}>
|
|
59
|
+
{<View testID={testID+"_Containter"} {...containerProps} style={[mainStyles.container,containerProps.style,styles.container,{left:win.width-10},!visible &&{display:'none',width:0,opacity:0}]}>
|
|
32
60
|
<ScrollView
|
|
33
61
|
{...props}
|
|
34
62
|
ref = {scrollViewRef}
|
|
@@ -42,7 +70,7 @@ const AbsoluteScrollView = React.forwardRef(({testID,contentProps,containerProps
|
|
|
42
70
|
style={[mainStyles.content,contentProps.style,styles.content]}
|
|
43
71
|
/>
|
|
44
72
|
</ScrollView>
|
|
45
|
-
</View>
|
|
73
|
+
</View>}
|
|
46
74
|
</Portal>
|
|
47
75
|
});
|
|
48
76
|
|
|
@@ -42,7 +42,7 @@ const getOnScrollCb = (refs,pos,cb2)=>{
|
|
|
42
42
|
return isMobileNative()? cb : debounce(cb,200);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
const TableComponent = React.forwardRef(({containerProps,isRowSelected,headerScrollViewProps,footerScrollViewProps,scrollViewProps,showFooters,renderFooterCell,footerCellContainerProps,headerContainerProps,headerCellContainerProps,headerProps,rowProps:customRowProps,renderCell,cellContainerProps,hasFooters,renderHeaderCell,columnProps,getRowKey,columnsWidths,colsWidths,footerContainerProps,showFilters,columns,data,testID,...props},tableRef)=>{
|
|
45
|
+
const TableComponent = React.forwardRef(({containerProps,renderEmpty,isRowSelected,headerScrollViewProps,footerScrollViewProps,scrollViewProps,showFooters,renderFooterCell,footerCellContainerProps,filterCellContainerProps,headerContainerProps,headerCellContainerProps,headerProps,rowProps:customRowProps,renderCell,cellContainerProps,hasFooters,renderHeaderCell,renderFilterCell,columnProps,getRowKey,columnsWidths,colsWidths,footerContainerProps,showFilters,columns,data,testID,...props},tableRef)=>{
|
|
46
46
|
containerProps = defaultObj(containerProps);
|
|
47
47
|
testID = defaultStr(testID,"RN_TableComponent");
|
|
48
48
|
cellContainerProps = defaultObj(cellContainerProps);
|
|
@@ -53,13 +53,14 @@ const TableComponent = React.forwardRef(({containerProps,isRowSelected,headerScr
|
|
|
53
53
|
const getRowProps = typeof rowProps ==='function'? rowProps : undefined;
|
|
54
54
|
let rowProps = isObj(customRowProps)? customRowProps:{};
|
|
55
55
|
const prepareState = React.useCallback(()=>{
|
|
56
|
-
const cols = {},headers = {},footers = {},visibleColumns = [];
|
|
56
|
+
const cols = {},headers = {},footers = {},filters = {},visibleColumns = [];
|
|
57
57
|
let hasFooters = false;
|
|
58
58
|
columnProps = defaultObj(columnProps);
|
|
59
59
|
let columnIndex = 0;
|
|
60
60
|
const widths = defaultObj(columnsWidths,colsWidths);
|
|
61
61
|
headerCellContainerProps = defaultObj(headerCellContainerProps);
|
|
62
62
|
footerCellContainerProps = defaultObj(footerCellContainerProps);
|
|
63
|
+
filterCellContainerProps = defaultObj(filterCellContainerProps);
|
|
63
64
|
Object.map(columns,(columnDef,field)=>{
|
|
64
65
|
if(!isObj(columnDef) /*|| columnDef.visible === false*/) return;
|
|
65
66
|
const columnField = defaultStr(columnDef.field,field);
|
|
@@ -85,6 +86,12 @@ const TableComponent = React.forwardRef(({containerProps,isRowSelected,headerScr
|
|
|
85
86
|
headers[columnField] = <View testID={testID+"_HeaderCell_"+columnField} {...headerCellContainerProps} {...hContainerProps} key={columnField} style={[styles.headerItem,styles.headerItemOrCell,headerCellContainerProps.style,hContainerProps.style,style]}>
|
|
86
87
|
<Label textBold primary>{content}</Label>
|
|
87
88
|
</View>;
|
|
89
|
+
if(typeof renderFilterCell =='function'){
|
|
90
|
+
const filterCell = renderFilterCell(colArgs);
|
|
91
|
+
filters[columnField] = <View testID={testID+"_Filter_Cell_"+columnField} {...filterCellContainerProps} key={columnField} style={[styles.headerItem,styles.headerItemOrCell,styles.filterCell,filterCellContainerProps.style,style]}>
|
|
92
|
+
{React.isValidElement(filterCell)? filterCell : null}
|
|
93
|
+
</View>
|
|
94
|
+
}
|
|
88
95
|
if(typeof renderFooterCell ==='function') {
|
|
89
96
|
const footerProps = {...colArgs,containerProps:{}};
|
|
90
97
|
let cellFooter = renderFooterCell(footerProps);
|
|
@@ -99,7 +106,7 @@ const TableComponent = React.forwardRef(({containerProps,isRowSelected,headerScr
|
|
|
99
106
|
if(!hasFooters && cellFooter){
|
|
100
107
|
hasFooters = true;
|
|
101
108
|
}
|
|
102
|
-
footers[columnField] = <View testID={testID+"_Footer_Cell_"+columnField}
|
|
109
|
+
footers[columnField] = <View testID={testID+"_Footer_Cell_"+columnField} key={columnField} style={[styles.headerItem,styles.headerItemOrCell,footerCellContainerProps.style,style]}>
|
|
103
110
|
<Label primary children={cellFooter}/>
|
|
104
111
|
</View>
|
|
105
112
|
}
|
|
@@ -116,7 +123,7 @@ const TableComponent = React.forwardRef(({containerProps,isRowSelected,headerScr
|
|
|
116
123
|
}
|
|
117
124
|
columnIndex++;
|
|
118
125
|
});
|
|
119
|
-
return {columns:cols,visibleColumns,headers,hasFooters,footers};
|
|
126
|
+
return {columns:cols,visibleColumns,headers,hasFooters,footers,filters};
|
|
120
127
|
},[columns,data]);
|
|
121
128
|
const [state,setState] = React.useState({
|
|
122
129
|
headers : {},
|
|
@@ -129,11 +136,13 @@ const TableComponent = React.forwardRef(({containerProps,isRowSelected,headerScr
|
|
|
129
136
|
React.useEffect(()=>{
|
|
130
137
|
setState({...state,...prepareState()});
|
|
131
138
|
},[data,columns]);
|
|
132
|
-
const
|
|
139
|
+
const emptyData = typeof renderEmpty =='function' && !Object.size(data,true)? renderEmpty() : null;
|
|
140
|
+
const hasEmptyData = emptyData && React.isValidElement(emptyData);
|
|
141
|
+
const {visibleColumns,columns:cols,headers,footers,filters} = state;
|
|
133
142
|
headerContainerProps = defaultObj(headerContainerProps);
|
|
134
143
|
footerContainerProps = defaultObj(footerContainerProps);
|
|
135
144
|
let hProps = typeof headerProps =='function'? hProps({columns:col,visibleColumns}) : {};
|
|
136
|
-
const h = [],f = [];
|
|
145
|
+
const h = [],f = [],fFilters = [];
|
|
137
146
|
let totalWidths = 0;
|
|
138
147
|
visibleColumns.map((i)=>{
|
|
139
148
|
if(!isObj(cols[i])) return;
|
|
@@ -142,6 +151,9 @@ const TableComponent = React.forwardRef(({containerProps,isRowSelected,headerScr
|
|
|
142
151
|
if(showFooters && state.hasFooters){
|
|
143
152
|
f.push(footers[i]);
|
|
144
153
|
}
|
|
154
|
+
if(showFilters && filters[i]){
|
|
155
|
+
fFilters.push(filters[i]);
|
|
156
|
+
}
|
|
145
157
|
});
|
|
146
158
|
const scrollContentContainerStyle = {flex:1,width:listWidth,minWidth:totalWidths,height:'100%'};
|
|
147
159
|
const scrollEventThrottle = isMobileNative()?200:50;
|
|
@@ -150,7 +162,7 @@ const TableComponent = React.forwardRef(({containerProps,isRowSelected,headerScr
|
|
|
150
162
|
scrollEventThrottle,
|
|
151
163
|
horizontal : true,
|
|
152
164
|
...scrollViewProps,
|
|
153
|
-
style : [
|
|
165
|
+
style : [scrollViewProps.style],
|
|
154
166
|
contentContainerStyle : [styles.scrollView,scrollViewProps.contentContainerStyle,scrollViewFlexGrow,scrollContentContainerStyle]
|
|
155
167
|
}
|
|
156
168
|
const listWidth = '100%';
|
|
@@ -187,15 +199,19 @@ const TableComponent = React.forwardRef(({containerProps,isRowSelected,headerScr
|
|
|
187
199
|
const hContent = h.length ? <View testID={testID+"_Header"}{...hProps} {...headerContainerProps} style={[styles.header,headerContainerProps.style,hProps.style,f.length]}>
|
|
188
200
|
{h}
|
|
189
201
|
</View> : null,
|
|
190
|
-
|
|
202
|
+
fContent = f.length ? <View testID={testID+"_Footer"} {...footerContainerProps} style={[styles.header,styles.footers,footerContainerProps.style,theme.styles.pt0,theme.styles.pb0,theme.styles.ml0,theme.styles.mr0]}>
|
|
191
203
|
{f}
|
|
192
|
-
</View> : null
|
|
204
|
+
</View> : null,
|
|
205
|
+
filtersContent = fFilters.length ? <View testID={testID+"_Filters"} style={[styles.header,styles.footers,theme.styles.pt0,theme.styles.pb0,theme.styles.ml0,theme.styles.mr0]}>
|
|
206
|
+
{fFilters}
|
|
207
|
+
</View> : null
|
|
208
|
+
|
|
193
209
|
const absoluteScrollViewRefCanScroll = React.useRef(true);
|
|
194
210
|
React.setRef(tableRef,context);
|
|
195
211
|
const cStyle = {width:listWidth}
|
|
196
212
|
const absoluteScrollViewRef = React.useRef(null);
|
|
197
|
-
return <View testID= {testID+"_Container"} {...containerProps} style={[styles.container,{alignItems:'stretch'},containerProps.style]}>
|
|
198
|
-
<
|
|
213
|
+
return <View testID= {testID+"_Container"} {...containerProps} style={[styles.container,{alignItems:'stretch'},containerProps.style,theme.styles.pl0,theme.styles.pr0]}>
|
|
214
|
+
<RNView style={[cStyle]} testID={testID+"_Headers_ScrollViewContainer"}>
|
|
199
215
|
<ScrollView
|
|
200
216
|
testID={testID+"_HeaderScrollView"}
|
|
201
217
|
{...headerScrollViewProps}
|
|
@@ -205,12 +221,22 @@ const TableComponent = React.forwardRef(({containerProps,isRowSelected,headerScr
|
|
|
205
221
|
onScroll = {getOnScrollCb([scrollViewRef,footerScrollViewRef])}
|
|
206
222
|
showsHorizontalScrollIndicator
|
|
207
223
|
>
|
|
208
|
-
{
|
|
224
|
+
<View testID={testID+"Header2FootersWrapper"} style={[theme.styles.w100]}>
|
|
225
|
+
{hContent}
|
|
226
|
+
{filtersContent}
|
|
227
|
+
{fContent}
|
|
228
|
+
</View>
|
|
209
229
|
</ScrollView>
|
|
210
|
-
</
|
|
211
|
-
|
|
230
|
+
</RNView>
|
|
231
|
+
{hasEmptyData ? <View testID={testID+"_Empty"} style={styles.hasNotData}>
|
|
232
|
+
{emptyData}
|
|
233
|
+
</View> : <ScrollView {...scrollViewProps} scrollEventThrottle = {scrollEventThrottle} horizontal contentContainerStyle={[scrollContentContainerStyle,scrollViewProps.contentContainerStyle]} showsVerticalScrollIndicator={false}
|
|
212
234
|
onScroll = {getOnScrollCb([headerScrollViewRef,footerScrollViewRef],null,(args)=>{
|
|
213
|
-
|
|
235
|
+
const nativeEvent = args.nativeEvent;
|
|
236
|
+
if(absoluteScrollViewRef.current && absoluteScrollViewRef.current.checkVisibility){
|
|
237
|
+
absoluteScrollViewRef.current.checkVisibility(nativeEvent);
|
|
238
|
+
}
|
|
239
|
+
})} ref={scrollViewRef} testID={testID+"_ScrollView"}>
|
|
214
240
|
<FlashList
|
|
215
241
|
containerProps = {{style:[cStyle]}}
|
|
216
242
|
//prepareItems = {Array.isArray(items)? false : undefined}
|
|
@@ -222,7 +248,7 @@ const TableComponent = React.forwardRef(({containerProps,isRowSelected,headerScr
|
|
|
222
248
|
}
|
|
223
249
|
if(!absoluteScrollViewRef.current) return;
|
|
224
250
|
absoluteScrollViewRef.current.setStyles({
|
|
225
|
-
content : {height}
|
|
251
|
+
content : {height,width}
|
|
226
252
|
});
|
|
227
253
|
}}
|
|
228
254
|
onLayout = {(args)=>{
|
|
@@ -248,6 +274,7 @@ const TableComponent = React.forwardRef(({containerProps,isRowSelected,headerScr
|
|
|
248
274
|
keyExtractor = {typeof getRowKey =='function'? getRowKey : React.getKey}
|
|
249
275
|
//stickyHeaderIndices={[0]}
|
|
250
276
|
onScroll = {getOnScrollCb([absoluteScrollViewRef],(args)=>{
|
|
277
|
+
if(!absoluteScrollViewRef.current) return;
|
|
251
278
|
const offset = args?.nativeEvent?.contentOffset.y;
|
|
252
279
|
const scrollViewRef = absoluteScrollViewRef.current?.scrollViewRef;
|
|
253
280
|
if(typeof offset =='number' && scrollViewRef.current && scrollViewRef.current.scrollTo){
|
|
@@ -286,18 +313,20 @@ const TableComponent = React.forwardRef(({containerProps,isRowSelected,headerScr
|
|
|
286
313
|
</View>;
|
|
287
314
|
}}
|
|
288
315
|
/>
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
listRef.current.scrollToOffset
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
316
|
+
<AbsoluteScrollView
|
|
317
|
+
ref={absoluteScrollViewRef}
|
|
318
|
+
listRef = {listRef}
|
|
319
|
+
scrollEventThrottle = {scrollEventThrottle}
|
|
320
|
+
onScroll = {(args)=>{
|
|
321
|
+
if(!absoluteScrollViewRefCanScroll.current) return;
|
|
322
|
+
const offset = args?.nativeEvent?.contentOffset.y;
|
|
323
|
+
if(typeof offset =='number' && listRef.current && listRef.current.scrollToOffset){
|
|
324
|
+
listRef.current.scrollToOffset({animated:true,offset});
|
|
325
|
+
}
|
|
326
|
+
}}
|
|
327
|
+
/>
|
|
328
|
+
</ScrollView>}
|
|
329
|
+
|
|
301
330
|
</View>
|
|
302
331
|
});
|
|
303
332
|
|
|
@@ -358,6 +387,15 @@ const styles = StyleSheet.create({
|
|
|
358
387
|
paddingHorizontal:5,
|
|
359
388
|
paddingVertical : 0,
|
|
360
389
|
},
|
|
390
|
+
filterCell : {
|
|
391
|
+
alignSelf : "flex-start",
|
|
392
|
+
textAlign : "left",
|
|
393
|
+
paddingHorizontal : 2,
|
|
394
|
+
paddingVertical : 0,
|
|
395
|
+
marginVertical : 0,
|
|
396
|
+
marginHorizontal : 0,
|
|
397
|
+
justifyContent : 'flex-start',
|
|
398
|
+
},
|
|
361
399
|
headerItem: {
|
|
362
400
|
minHeight: 30,
|
|
363
401
|
},
|
|
@@ -377,14 +415,22 @@ const styles = StyleSheet.create({
|
|
|
377
415
|
marginHorizontal : 0,
|
|
378
416
|
marginVertical : 0,
|
|
379
417
|
},
|
|
418
|
+
hasNotData : {
|
|
419
|
+
flexDirection : 'column',
|
|
420
|
+
width : '100%',
|
|
421
|
+
justifyContent : 'center',
|
|
422
|
+
alignItems : 'center'
|
|
423
|
+
}
|
|
380
424
|
})
|
|
381
425
|
TableComponent.popTypes = {
|
|
382
426
|
containerProps : PropTypes.object,
|
|
383
427
|
renderHeaderCell : PropTypes.func,
|
|
428
|
+
renderFilterCell : PropTypes.func,
|
|
384
429
|
renderRow : PropTypes.func,
|
|
385
430
|
renderCell : PropTypes.func,
|
|
386
431
|
renderFooterCell : PropTypes.func,///la fonction appelée pour le rendu des entêtes du footer
|
|
387
432
|
footerCellContainerProps : PropTypes.object,
|
|
433
|
+
filterCellContainerProps : PropTypes.object,
|
|
388
434
|
footerContainerProps : PropTypes.object,
|
|
389
435
|
showFilters : PropTypes.bool,
|
|
390
436
|
showFooters : PropTypes.bool,
|
|
@@ -244,12 +244,12 @@ const TextFieldComponent = React.forwardRef((componentProps,inputRef)=>{
|
|
|
244
244
|
if(isFocused || error){
|
|
245
245
|
placeholderColor = labelColor;
|
|
246
246
|
}
|
|
247
|
+
let labelText = React.isValidElement(label,true)?React.getTextContent(label):"";
|
|
247
248
|
const defaultBackgroundColor = theme.surfaceBackgroundColor;
|
|
248
249
|
let backgroundColor = Colors.isValid(flattenStyle.backgroundColor)? flattenStyle.backgroundColor : defaultBackgroundColor;
|
|
249
|
-
if(backgroundColor ==='transparent' && dynamicBackgroundColor !== false){
|
|
250
|
+
if(labelText && (backgroundColor ==='transparent' && dynamicBackgroundColor !== false)){
|
|
250
251
|
backgroundColor = defaultBackgroundColor;
|
|
251
252
|
}
|
|
252
|
-
let labelText = React.isValidElement(label,true)?React.getTextContent(label):"";
|
|
253
253
|
placeholder = defaultStr(placeholder,labelText);
|
|
254
254
|
const parsedValue = canValueBeDecimal ? parseValueToDecimal(text):text;
|
|
255
255
|
const formattedValue = formatValue(text);
|