@fto-consult/expo-ui 6.24.2 → 6.25.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/app.config.json +1 -1
- package/babel.config.alias.js +2 -1
- package/babel.config.js +1 -1
- package/electron/utils/env.js +80 -0
- package/expo-ui-path.js +2 -2
- package/index.js +14 -13
- package/is-local-dev.js +5 -0
- package/metro.config.js +3 -2
- package/package.json +7 -4
- package/readChart.txt +4 -1
- package/src/App.js +3 -3
- package/src/components/Datagrid/Accordion/Row.js +74 -100
- package/src/components/Datagrid/Accordion/ToogleRow.js +9 -0
- package/src/components/Datagrid/Accordion/index.js +30 -35
- package/src/components/Datagrid/Actions/index.js +12 -44
- package/src/components/Datagrid/Checkbox.js +4 -7
- package/src/components/Datagrid/Common/Common.js +121 -152
- package/src/components/Datagrid/Dashboard/index.js +2 -2
- package/src/components/Datagrid/IndexComponent.js +8 -13
- package/src/components/Datagrid/Table/index.js +53 -51
- package/src/components/Datagrid/Test/index.js +10 -3
- package/src/components/Datagrid/events/evx.js +7 -0
- package/src/components/Datagrid/events/index.js +11 -0
- package/src/components/Datagrid/hooks/Provider.js +6 -0
- package/src/components/Datagrid/hooks/context.js +5 -0
- package/src/components/Datagrid/hooks/index.js +104 -0
- package/src/components/Datagrid/utils.js +8 -5
- package/src/components/Dialog/Dialog.js +13 -12
- package/src/components/Dialog/DialogContent.js +11 -0
- package/src/components/KeyboardAvoidingView/index.js +7 -3
- package/src/components/Label/index.js +8 -4
- package/src/components/List/Common.js +5 -3
- package/src/components/List/FlashList.js +13 -13
- package/src/components/List/Virtuoso/index.js +68 -10
- package/src/components/List/Virtuoso/index.native.js +6 -1
- package/src/components/Table/Header/Cell/index.js +10 -0
- package/src/components/Table/Header/Cell/index.native.js +7 -0
- package/src/components/Table/Header/index.js +34 -0
- package/src/components/Table/List/index.js +3 -1
- package/src/components/Table/List/index.native.js +2 -1
- package/src/components/Table/Row/Cell/Content.js +16 -0
- package/src/components/Table/Row/Cell/Content.native.js +15 -0
- package/src/components/Table/Row/Cell/index.js +30 -0
- package/src/components/Table/Row/RowWrapper.js +7 -0
- package/src/components/Table/Row/RowWrapper.native.js +11 -0
- package/src/components/Table/Row/index.js +38 -0
- package/src/components/Table/RowTemplate/index.js +10 -0
- package/src/components/Table/RowTemplate/index.web.js +9 -0
- package/src/components/Table/ScrollNative/index.js +7 -0
- package/src/components/Table/ScrollNative/index.native.js +8 -0
- package/src/components/Table/VirtuosoTable/index.js +5 -0
- package/src/components/Table/VirtuosoTable/index.native.js +3 -0
- package/src/components/Table/hooks.js +84 -0
- package/src/components/Table/index.js +92 -250
- package/src/components/Table/styles.js +104 -0
- package/src/components/Table/utils.js +1 -0
- package/src/context/Provider.js +16 -2
- package/src/layouts/AppBar/index.js +11 -10
- package/src/layouts/Screen/ScreenWithoutAuthContainer.js +14 -6
- package/src/navigation/Drawer/items/index.js +2 -1
- package/src/navigation/index.js +11 -3
- package/src/screens/Help/About.js +1 -1
- package/src/screens/Help/openLibraries.js +1 -1
- package/src/test-screens/Home.js +4 -1
- package/webpack.config.js +4 -2
- package/src/components/Table/Cell.js +0 -24
- package/src/components/Table/FiltersOrFooters.js +0 -18
- package/src/components/Table/Header.js +0 -25
- package/src/components/Table/Row.js +0 -21
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import View from "$ecomponents/View";
|
|
2
|
-
import {defaultObj,defaultStr,debounce,defaultNumber,defaultVal} from "$cutils";
|
|
2
|
+
import {defaultObj,defaultStr,debounce,defaultNumber,isObj,defaultVal} from "$cutils";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
|
-
export const DEFAULT_COLUMN_WIDTH = 60;
|
|
5
4
|
import React from "$react";
|
|
6
|
-
import Label from "$ecomponents/Label";
|
|
7
5
|
import { StyleSheet,View as RNView,ScrollView,Dimensions} from "react-native";
|
|
8
|
-
import { getRowStyle } from "$ecomponents/Datagrid/utils";
|
|
9
6
|
import {isMobileNative} from "$cplatform";
|
|
10
7
|
import theme from "$theme";
|
|
11
8
|
import AbsoluteScrollView from "./AbsoluteScrollView";
|
|
12
|
-
import Cell from "./Cell";
|
|
13
9
|
import Row from "./Row";
|
|
14
|
-
import List from "./List";
|
|
15
|
-
import
|
|
10
|
+
import List,{TableRowComponent} from "./List";
|
|
11
|
+
import Header from "./Header";
|
|
12
|
+
import { usePrepareColumns,TableContext,useTable} from "./hooks";
|
|
13
|
+
import styles from "./styles";
|
|
14
|
+
import {useIsRowSelected} from "$ecomponents/Datagrid/hooks";
|
|
15
|
+
import {getRowStyle} from "$ecomponents/Datagrid/utils";
|
|
16
|
+
import ScrollNative from "./ScrollNative";
|
|
17
|
+
import VirtuosoTableComponent from "./VirtuosoTable";
|
|
18
|
+
export {styles};
|
|
19
|
+
|
|
16
20
|
const isSCrollingRef = React.createRef();
|
|
21
|
+
const isNative = isMobileNative();
|
|
22
|
+
|
|
23
|
+
export * from "./utils";
|
|
17
24
|
const scrollLists = (opts,refs)=>{
|
|
18
25
|
refs.map((ref)=>{
|
|
19
26
|
if(ref && ref.current && ref.current.scrollTo){
|
|
@@ -44,99 +51,27 @@ const getOnScrollCb = (refs,pos,cb2)=>{
|
|
|
44
51
|
return isMobileNative()? cb : debounce(cb,200);
|
|
45
52
|
}
|
|
46
53
|
|
|
47
|
-
const TableComponent = React.forwardRef(({containerProps,
|
|
54
|
+
const TableComponent = React.forwardRef(({containerProps,listContainerStyle,onRender,height,progressBar,renderListContent,children,renderEmpty,renderItem,isRowSelected,headerScrollViewProps,footerScrollViewProps,scrollViewProps,showFooters,renderFooterCell,footerCellContainerProps,filterCellContainerProps,headerContainerProps,headerCellContainerProps,headerProps,rowProps:customRowProps,cellContainerProps,hasFooters,renderHeaderCell,renderFilterCell,columnProps,getRowKey,columnsWidths,colsWidths,footerContainerProps,showHeaders,showFilters,columns,...props},tableRef)=>{
|
|
48
55
|
containerProps = defaultObj(containerProps);
|
|
49
|
-
testID = defaultStr(testID,"RN_TableComponent");
|
|
50
56
|
cellContainerProps = defaultObj(cellContainerProps);
|
|
51
57
|
scrollViewProps = defaultObj(scrollViewProps);
|
|
52
58
|
headerScrollViewProps = defaultObj(headerScrollViewProps);
|
|
53
59
|
footerScrollViewProps = defaultObj(footerScrollViewProps);
|
|
54
|
-
renderCell = typeof renderCell ==="function"? renderCell : undefined;
|
|
55
|
-
const getRowProps = typeof rowProps ==='function'? rowProps : undefined;
|
|
56
|
-
let rowProps = isObj(customRowProps)? customRowProps:{};
|
|
57
60
|
const listRef = React.useRef(null),scrollViewRef = React.useRef(null),headerScrollViewRef = React.useRef(null);
|
|
58
|
-
const emptyData = renderListContent === false ?null : typeof renderEmpty =='function' && !Object.size(data,true)? renderEmpty() : null;
|
|
59
|
-
const hasEmptyData = emptyData && React.isValidElement(emptyData);
|
|
60
61
|
const layoutRef = React.useRef({});
|
|
61
|
-
|
|
62
|
-
const preparedColumns = React.useMemo(()=>{
|
|
63
|
-
const cols = {},headers = {},footers = {},filters = {},vColumnsMapping = [],visibleColumns = [],columnsNames = [];
|
|
64
|
-
let hasFooters = false;
|
|
65
|
-
columnProps = defaultObj(columnProps);
|
|
66
|
-
let columnIndex = 0;
|
|
67
|
-
const widths = defaultObj(columnsWidths,colsWidths);
|
|
68
|
-
headerCellContainerProps = defaultObj(headerCellContainerProps);
|
|
69
|
-
footerCellContainerProps = defaultObj(footerCellContainerProps);
|
|
70
|
-
filterCellContainerProps = defaultObj(filterCellContainerProps);
|
|
71
|
-
Object.map(columns,(columnDef,field)=>{
|
|
72
|
-
if(!isObj(columnDef)) return;
|
|
73
|
-
const columnField = defaultStr(columnDef.field,field);
|
|
74
|
-
let {visible,width,type,...colProps} = columnDef;
|
|
75
|
-
visible = typeof visible =='boolean'? visible : true;
|
|
76
|
-
type = defaultStr(type,"text").toLowerCase().trim();
|
|
77
|
-
colProps = defaultObj(colProps);
|
|
78
|
-
width = defaultDecimal(widths[columnField],width,DEFAULT_COLUMN_WIDTH);
|
|
79
|
-
const style = StyleSheet.flatten([colProps.style,{width}]);
|
|
80
|
-
const colArgs = {width,type,style,columnDef,containerProps:{},columnField,index:columnIndex,columnIndex};
|
|
81
|
-
const content = typeof renderHeaderCell =='function'? renderHeaderCell(colArgs) : defaultVal(columnDef.text,columnDef.label,columnField);
|
|
82
|
-
const hContainerProps = defaultObj(colArgs.containerProps);
|
|
83
|
-
if(!React.isValidElement(content,true)){
|
|
84
|
-
console.error(content," is not valid element of header ",columnDef," it could not be render on table");
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
headers[columnField] = <View testID={testID+"_HeaderCell_"+columnField} {...headerCellContainerProps} {...hContainerProps} key={columnField} style={[styles.headerItem,styles.headerItemOrCell,headerCellContainerProps.style,hContainerProps.style,style]}>
|
|
88
|
-
<Label splitText numberOfLines={2} style={[theme.styles.w100,theme.styles.h100,{maxHeight:70}]} textBold primary>{content}</Label>
|
|
89
|
-
</View>;
|
|
90
|
-
if(typeof renderFilterCell =='function'){
|
|
91
|
-
const filterCell = renderFilterCell(colArgs);
|
|
92
|
-
filters[columnField] = <View testID={testID+"_Filter_Cell_"+columnField} {...filterCellContainerProps} key={columnField} style={[styles.headerItem,styles.headerItemOrCell,styles.filterCell,filterCellContainerProps.style,style]}>
|
|
93
|
-
{React.isValidElement(filterCell)? filterCell : null}
|
|
94
|
-
</View>
|
|
95
|
-
}
|
|
96
|
-
if(typeof renderFooterCell ==='function') {
|
|
97
|
-
const footerProps = {...colArgs,containerProps:{}};
|
|
98
|
-
let cellFooter = renderFooterCell(footerProps);
|
|
99
|
-
let fContainerProps = {};
|
|
100
|
-
if(!React.isValidElement(cellFooter,true) && isObj(cellFooter)){
|
|
101
|
-
fContainerProps = isObj(cellFooter.containerProps)? cellFooter.containerProps : {};
|
|
102
|
-
cellFooter = React.isValidElement(cellFooter.children)? cellFooter.children : React.isValidElement(cellFooter.content)? cellFooter.content : null;
|
|
103
|
-
} else if(isObj(footerProps.containerProps)){
|
|
104
|
-
fContainerProps = footerProps.containerProps;
|
|
105
|
-
}
|
|
106
|
-
cellFooter = React.isValidElement(cellFooter,true)? cellFooter : null;
|
|
107
|
-
if(!hasFooters && cellFooter){
|
|
108
|
-
hasFooters = true;
|
|
109
|
-
}
|
|
110
|
-
footers[columnField] = <View testID={testID+"_Footer_Cell_"+columnField} key={columnField} style={[styles.headerItem,styles.headerItemOrCell,footerCellContainerProps.style,style]}>
|
|
111
|
-
<Label primary children={cellFooter}/>
|
|
112
|
-
</View>
|
|
113
|
-
}
|
|
114
|
-
vColumnsMapping.push(visible);
|
|
115
|
-
if(visible){
|
|
116
|
-
visibleColumns.push(columnField);
|
|
117
|
-
}
|
|
118
|
-
columnsNames.push(columnField);
|
|
119
|
-
cols[columnField] = {
|
|
120
|
-
...columnDef,
|
|
121
|
-
width,
|
|
122
|
-
index : columnIndex,
|
|
123
|
-
field : columnField,
|
|
124
|
-
visible,
|
|
125
|
-
columnField,
|
|
126
|
-
};
|
|
127
|
-
columnIndex++;
|
|
128
|
-
});
|
|
129
|
-
return {columns:cols,columnsNames,headers,visibleColumns,vColumnsMapping,hasFooters,footers,filters};
|
|
130
|
-
},[columns,sortedColumn,props.footers]);
|
|
131
|
-
const {columns:cols,headers,footers,filters,hasFooters:stateHasFooters,columnsNames,vColumnsMapping,visibleColumns} = preparedColumns;
|
|
62
|
+
const {columns:cols,testID,headers,footers,getItem,withDatagridContext,filters,getRowByIndex,itemsChanged,hasFooters:stateHasFooters,visibleColsNames,keyExtractor,items,data} = useTable();
|
|
132
63
|
headerContainerProps = defaultObj(headerContainerProps);
|
|
133
64
|
footerContainerProps = defaultObj(footerContainerProps);
|
|
134
|
-
const
|
|
135
|
-
const
|
|
65
|
+
const hasData = !!Object.size(data,true);
|
|
66
|
+
const emptyData = !hasData && renderListContent === false ?null : typeof renderEmpty =='function' ? renderEmpty() : null;
|
|
67
|
+
const hasEmptyData = emptyData && React.isValidElement(emptyData);
|
|
68
|
+
const emptyContent = <View onRender={onComponentRender} testID={testID+"_EmptyData"} style={styles.hasNotData}>
|
|
69
|
+
{emptyData}
|
|
70
|
+
</View>
|
|
136
71
|
const {fFilters,headersContent,footersContent,totalWidths} = React.useMemo(()=>{
|
|
137
72
|
const headersContent = [],footersContent = [],fFilters = [];
|
|
138
73
|
let totalWidths = 0;
|
|
139
|
-
|
|
74
|
+
visibleColsNames.map((i,index)=>{
|
|
140
75
|
headersContent.push(headers[i]);
|
|
141
76
|
totalWidths+=cols[i].width;
|
|
142
77
|
if(showFooters && stateHasFooters){
|
|
@@ -148,50 +83,9 @@ const TableComponent = React.forwardRef(({containerProps,sortedColumn,listContai
|
|
|
148
83
|
});
|
|
149
84
|
|
|
150
85
|
return {headersContent,totalWidths,footersContent,fFilters};
|
|
151
|
-
},[
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const itemsRef = React.useRef(null);
|
|
155
|
-
const hasChangedDataRef = React.useRef(false);
|
|
156
|
-
hasChangedDataRef.current = false;
|
|
157
|
-
const items = React.useMemo(()=>{
|
|
158
|
-
if(data === prevData && prevColumns == columns && Array.isArray(itemsRef.current)){
|
|
159
|
-
hasChangedDataRef.current = false;
|
|
160
|
-
return itemsRef.current;
|
|
161
|
-
}
|
|
162
|
-
hasChangedDataRef.current = true;
|
|
163
|
-
const items = [];
|
|
164
|
-
const filter = typeof customFilter =='function'? customFilter : x=>true;
|
|
165
|
-
data.map((item,index)=>{
|
|
166
|
-
const rowIndex = index;
|
|
167
|
-
if(!isObj(item) || filter({item,index,_index:rowIndex}) ===false) return null;
|
|
168
|
-
const rowArgs = {data:item,isTable:true,isAccordion:false,item,row:item,rowData:item,rowIndex,index};
|
|
169
|
-
const rProps = defaultObj(getRowProps ? getRowProps(rowArgs) : {});
|
|
170
|
-
rowArgs.rowProps = rProps;
|
|
171
|
-
rowArgs.rowStyle = rProps.style = StyleSheet.flatten([rowProps.style,getRowStyle(rowArgs),styles.rowNoPadding,rProps.style]);
|
|
172
|
-
if(item.isSectionListHeader){
|
|
173
|
-
rowArgs.isSectionListHeader = true;
|
|
174
|
-
}
|
|
175
|
-
const sItem = typeof renderItem == 'function'? renderItem(rowArgs) : undefined;
|
|
176
|
-
const cells = React.isValidElement(sItem) ? sItem : columnsNames.map((columnField,columnIndex)=>{
|
|
177
|
-
const columnDef = cols[columnField];
|
|
178
|
-
return <Cell
|
|
179
|
-
rowArgs = {rowArgs}
|
|
180
|
-
style = {StyleSheet.flatten([styles.headerItemOrCell,{width:columnDef.width}])}
|
|
181
|
-
//key = {"_Cell_"+columnField+"_"+index}
|
|
182
|
-
cellArgs={{columnIndex,columnDef,columnField:columnField}}
|
|
183
|
-
renderCell = {renderCell}
|
|
184
|
-
rowIndex = {index}
|
|
185
|
-
children = {item[columnField]}
|
|
186
|
-
testID={testID+"_Cell_"+columnField+"_"+index}
|
|
187
|
-
/>
|
|
188
|
-
});
|
|
189
|
-
if(!Array.isArray(cells) && !React.isValidElement(cells)) return null;
|
|
190
|
-
items.push(<Row cells={cells} columns={vColumnsMapping} testID={testID+"_Row_"+index} {...rowProps} {...rProps} style={[styles.row,rProps.style]}/>);
|
|
191
|
-
});
|
|
192
|
-
itemsRef.current = items;
|
|
193
|
-
return items;
|
|
194
|
-
},[data,columns]);
|
|
86
|
+
},[visibleColsNames,showFilters,showFooters,layoutRef.current]);
|
|
87
|
+
|
|
88
|
+
|
|
195
89
|
const scrollContentContainerStyle = {flex:1,width:listWidth,minWidth:totalWidths,height:'100%'};
|
|
196
90
|
const scrollEventThrottle = isMobileNative()?200:50;
|
|
197
91
|
const scrollViewFlexGrow = {flexGrow:0};
|
|
@@ -255,7 +149,7 @@ const TableComponent = React.forwardRef(({containerProps,sortedColumn,listContai
|
|
|
255
149
|
onRender(a,b,c);
|
|
256
150
|
}
|
|
257
151
|
//au paravant il était possible de faire scroller le composant Table lorsque les données sont raffraichies, ce qui n'avait pas un bon impact sur le rendu de la table de données
|
|
258
|
-
if(false &&
|
|
152
|
+
if(false && itemsChanged){
|
|
259
153
|
//permet de restaurer la position scrollé où scroll initial à chaque fois que le composant est re render
|
|
260
154
|
//ce qui n'est pas très interessant
|
|
261
155
|
if(headerScrollViewRef.current && headerScrollViewRef.current.scrollTo){
|
|
@@ -267,14 +161,25 @@ const TableComponent = React.forwardRef(({containerProps,sortedColumn,listContai
|
|
|
267
161
|
}
|
|
268
162
|
}
|
|
269
163
|
};
|
|
164
|
+
const headerFootersFilters = <>
|
|
165
|
+
<Header visible={!!(showTableHeaders && headersContent.length)} testID={testID+"_Header"} {...headerContainerProps} style={[styles.header,headerContainerProps.style,footersContent.length]}>
|
|
166
|
+
{headersContent}
|
|
167
|
+
</Header>
|
|
168
|
+
<Header visible = {!!fFilters.length} {...headerContainerProps} testID={testID+"_Filters"} style={[styles.header,styles.footers,theme.styles.pt0,theme.styles.pb0,theme.styles.ml0,theme.styles.mr0,headerContainerProps.style]}>
|
|
169
|
+
{fFilters}
|
|
170
|
+
</Header>
|
|
171
|
+
<Header visible={!!(showTableHeaders && footersContent.length)} testID={testID+"_Footer"} {...footerContainerProps} style={[styles.header,styles.footers,headerContainerProps.style,footerContainerProps.style,theme.styles.pt0,theme.styles.pb0,theme.styles.ml0,theme.styles.mr0]}>
|
|
172
|
+
{footersContent}
|
|
173
|
+
</Header>
|
|
174
|
+
</>
|
|
270
175
|
return <View testID= {testID+"_Container"} {...containerProps} onLayout={(e)=>{
|
|
271
176
|
layoutRef.current = e.nativeEvent.layout;
|
|
272
177
|
if(containerProps.onLayout){
|
|
273
178
|
containerProps.onLayout(e);
|
|
274
179
|
}
|
|
275
180
|
}} style={[styles.container,{alignItems:'stretch'},containerProps.style]}>
|
|
276
|
-
<RNView style={[cStyle]} testID={testID+"_Headers_ScrollViewContainer"}>
|
|
277
|
-
|
|
181
|
+
{isNative && <RNView style={[cStyle]} testID={testID+"_Headers_ScrollViewContainer"}>
|
|
182
|
+
<ScrollView
|
|
278
183
|
testID={testID+"_HeaderScrollView"}
|
|
279
184
|
{...headerScrollViewProps}
|
|
280
185
|
contentContainerStyle = {[allScrollViewProps.contentContainerStyle,headerScrollViewProps.contentContainerStyle,{flex:1,flexWrap: 'wrap'}]}
|
|
@@ -285,21 +190,11 @@ const TableComponent = React.forwardRef(({containerProps,sortedColumn,listContai
|
|
|
285
190
|
showsHorizontalScrollIndicator
|
|
286
191
|
>
|
|
287
192
|
<View testID={testID+"Header2FootersWrapper"} style={[theme.styles.w100]}>
|
|
288
|
-
|
|
289
|
-
{headersContent}
|
|
290
|
-
</FiltersOrFooters>
|
|
291
|
-
<FiltersOrFooters visible = {!!fFilters.length} testID={testID+"_Filters"} style={[styles.header,styles.footers,theme.styles.pt0,theme.styles.pb0,theme.styles.ml0,theme.styles.mr0]}>
|
|
292
|
-
{fFilters}
|
|
293
|
-
</FiltersOrFooters>
|
|
294
|
-
<FiltersOrFooters visible={!!(showTableHeaders && footersContent.length)} testID={testID+"_Footer"} {...footerContainerProps} style={[styles.header,styles.footers,footerContainerProps.style,theme.styles.pt0,theme.styles.pb0,theme.styles.ml0,theme.styles.mr0]}>
|
|
295
|
-
{footersContent}
|
|
296
|
-
</FiltersOrFooters>
|
|
193
|
+
{headerFootersFilters}
|
|
297
194
|
</View>
|
|
298
195
|
</ScrollView>
|
|
299
|
-
</RNView>
|
|
300
|
-
{hasEmptyData ? <
|
|
301
|
-
{emptyData}
|
|
302
|
-
</View> : <ScrollView {...scrollViewProps} scrollEventThrottle = {scrollEventThrottle} horizontal contentContainerStyle={[scrollContentContainerStyle,scrollViewProps.contentContainerStyle,{height:'100%'}]} showsVerticalScrollIndicator={false}
|
|
196
|
+
</RNView>}
|
|
197
|
+
{hasEmptyData && isNative ? emptyContent : <ScrollNative {...scrollViewProps} scrollEventThrottle = {scrollEventThrottle} horizontal contentContainerStyle={[scrollContentContainerStyle,scrollViewProps.contentContainerStyle,{height:'100%'}]} showsVerticalScrollIndicator={false}
|
|
303
198
|
onScroll = {getOnScrollCb([headerScrollViewRef,footerScrollViewRef],null,(args)=>{
|
|
304
199
|
const nativeEvent = args.nativeEvent;
|
|
305
200
|
if(absoluteScrollViewRef.current && absoluteScrollViewRef.current.checkVisibility){
|
|
@@ -325,6 +220,8 @@ const TableComponent = React.forwardRef(({containerProps,sortedColumn,listContai
|
|
|
325
220
|
<List
|
|
326
221
|
containerProps = {{style:[cStyle,listContainerStyle]}}
|
|
327
222
|
estimatedItemSize = {200}
|
|
223
|
+
renderTable
|
|
224
|
+
columns = {columns}
|
|
328
225
|
{...props}
|
|
329
226
|
onContentSizeChange = {(width,height)=>{
|
|
330
227
|
if(props.onContentSizeChange){
|
|
@@ -357,7 +254,7 @@ const TableComponent = React.forwardRef(({containerProps,sortedColumn,listContai
|
|
|
357
254
|
items = {items}
|
|
358
255
|
contentContainerStyle = {[styles.contentContainer,{width:listWidth,minWidth:totalWidths}]}
|
|
359
256
|
style = {[styles.datagrid,{width:listWidth,minWidth:totalWidths}]}
|
|
360
|
-
keyExtractor = {
|
|
257
|
+
keyExtractor = {keyExtractor}
|
|
361
258
|
onScroll = {getOnScrollCb([absoluteScrollViewRef],(args)=>{
|
|
362
259
|
if(!absoluteScrollViewRef.current) return;
|
|
363
260
|
const offset = args?.nativeEvent?.contentOffset.y;
|
|
@@ -370,26 +267,37 @@ const TableComponent = React.forwardRef(({containerProps,sortedColumn,listContai
|
|
|
370
267
|
},500);
|
|
371
268
|
}
|
|
372
269
|
})}
|
|
373
|
-
renderItem = {({index})=>
|
|
270
|
+
renderItem = {({item,index})=>{
|
|
271
|
+
return <Row rowData={item} index={index} testID={testID+"_Row_"+index}/>
|
|
272
|
+
}}
|
|
273
|
+
fixedHeaderContent={(index, user) => {
|
|
274
|
+
return headerFootersFilters;
|
|
275
|
+
}}
|
|
276
|
+
components = {{
|
|
277
|
+
TableRow: (props) => {
|
|
278
|
+
const index = props['data-index'];
|
|
279
|
+
const item = getRowByIndex(index) || props?.item || null;
|
|
280
|
+
if(!item) return null;
|
|
281
|
+
const args = {rowData:item,rowIndex:index,bordered:true,isTable:true};
|
|
282
|
+
args.isSelected = withDatagridContext ? isRowSelected(args) : false;
|
|
283
|
+
return <TableRowComponent {...props} style={[getRowStyle(args),props.style]}/>
|
|
284
|
+
},
|
|
285
|
+
Table: VirtuosoTableComponent,
|
|
286
|
+
}}
|
|
374
287
|
/>
|
|
375
|
-
<AbsoluteScrollView
|
|
288
|
+
{isNative ? <AbsoluteScrollView
|
|
376
289
|
ref={absoluteScrollViewRef}
|
|
377
290
|
listRef = {listRef}
|
|
378
291
|
scrollEventThrottle = {scrollEventThrottle}
|
|
379
292
|
onScroll = {(args)=>{
|
|
380
293
|
if(!absoluteScrollViewRefCanScroll.current || absoluteScrollingRef.current) return;
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
if(typeof offset =='number' && listRef.current && listRef.current.scrollToOffset){
|
|
386
|
-
listRef.current.scrollToOffset({animated:true,offset});
|
|
387
|
-
}
|
|
388
|
-
//absoluteScrollingRef.current = false;
|
|
389
|
-
//},100);
|
|
294
|
+
const offset = args?.nativeEvent?.contentOffset.y;
|
|
295
|
+
if(typeof offset =='number' && listRef.current && listRef.current.scrollToOffset){
|
|
296
|
+
listRef.current.scrollToOffset({animated:true,offset});
|
|
297
|
+
}
|
|
390
298
|
}}
|
|
391
|
-
|
|
392
|
-
</
|
|
299
|
+
/>:null}
|
|
300
|
+
</ScrollNative>}
|
|
393
301
|
|
|
394
302
|
</View>
|
|
395
303
|
});
|
|
@@ -403,96 +311,11 @@ const RowType = PropTypes.shape({
|
|
|
403
311
|
|
|
404
312
|
});
|
|
405
313
|
|
|
406
|
-
|
|
407
|
-
datagrid : {
|
|
408
|
-
flex:1,
|
|
409
|
-
},
|
|
410
|
-
contentContainer : {
|
|
411
|
-
flex:1,
|
|
412
|
-
},
|
|
413
|
-
container : {
|
|
414
|
-
width : '100%',
|
|
415
|
-
minHeight : 300,
|
|
416
|
-
paddingBottom : 10,
|
|
417
|
-
paddingLeft : 10,
|
|
418
|
-
paddingRight : 0,
|
|
419
|
-
flex : 1,
|
|
420
|
-
position : 'relative',
|
|
421
|
-
},
|
|
422
|
-
header2footerContainer:{
|
|
423
|
-
flexDirection : 'column',
|
|
424
|
-
width : '100%',
|
|
425
|
-
height : '100%',
|
|
426
|
-
minHeight : 50,
|
|
427
|
-
},
|
|
428
|
-
headerContainer : {
|
|
429
|
-
width : '100%',
|
|
430
|
-
flexDirection : 'row',
|
|
431
|
-
},
|
|
432
|
-
header: {
|
|
433
|
-
flexDirection: 'row',
|
|
434
|
-
paddingVertical : 7,
|
|
435
|
-
alignItems : 'center',
|
|
436
|
-
width : '100%',
|
|
437
|
-
},
|
|
438
|
-
footerContainer : {
|
|
439
|
-
width : '100%',
|
|
440
|
-
flexDirection : 'row',
|
|
441
|
-
flexWrap : 'wrap',
|
|
442
|
-
},
|
|
443
|
-
footers : {
|
|
444
|
-
minHeight : 40,
|
|
445
|
-
},
|
|
446
|
-
headerItemOrCell : {
|
|
447
|
-
alignItems: 'flex-start',
|
|
448
|
-
alignSelf : 'center',
|
|
449
|
-
height : '100%',
|
|
450
|
-
justifyContent: 'center',
|
|
451
|
-
textAlign : 'left',
|
|
452
|
-
flexWrap : 'wrap',
|
|
453
|
-
paddingHorizontal:5,
|
|
454
|
-
paddingVertical : 0,
|
|
455
|
-
},
|
|
456
|
-
filterCell : {
|
|
457
|
-
alignSelf : "flex-start",
|
|
458
|
-
textAlign : "left",
|
|
459
|
-
paddingHorizontal : 2,
|
|
460
|
-
paddingVertical : 0,
|
|
461
|
-
marginVertical : 0,
|
|
462
|
-
marginHorizontal : 0,
|
|
463
|
-
justifyContent : 'flex-start',
|
|
464
|
-
},
|
|
465
|
-
headerItem: {
|
|
466
|
-
minHeight: 30,
|
|
467
|
-
},
|
|
468
|
-
column : {
|
|
469
|
-
flexDirection : 'row',
|
|
470
|
-
justifyContent : 'center',
|
|
471
|
-
alignItems : 'flex-start',
|
|
472
|
-
},
|
|
473
|
-
row : {
|
|
474
|
-
flexDirection : "row",
|
|
475
|
-
justifyContent : "flex-start",
|
|
476
|
-
alignItems : 'flex-start',
|
|
477
|
-
width : '100%',
|
|
478
|
-
},
|
|
479
|
-
rowNoPadding : {
|
|
480
|
-
paddingHorizontal:0,
|
|
481
|
-
marginHorizontal : 0,
|
|
482
|
-
marginVertical : 0,
|
|
483
|
-
},
|
|
484
|
-
hasNotData : {
|
|
485
|
-
flexDirection : 'column',
|
|
486
|
-
width : '100%',
|
|
487
|
-
justifyContent : 'center',
|
|
488
|
-
alignItems : 'center'
|
|
489
|
-
}
|
|
490
|
-
})
|
|
314
|
+
|
|
491
315
|
TableComponent.popTypes = {
|
|
492
316
|
containerProps : PropTypes.object,
|
|
493
317
|
renderHeaderCell : PropTypes.func,
|
|
494
318
|
renderFilterCell : PropTypes.func,
|
|
495
|
-
renderRow : PropTypes.func,
|
|
496
319
|
renderCell : PropTypes.func,
|
|
497
320
|
renderFooterCell : PropTypes.func,///la fonction appelée pour le rendu des entêtes du footer
|
|
498
321
|
footerCellContainerProps : PropTypes.object,
|
|
@@ -510,7 +333,7 @@ TableComponent.popTypes = {
|
|
|
510
333
|
PropTypes.objectOf(ColumnType),
|
|
511
334
|
PropTypes.arrayOf(ColumnType)
|
|
512
335
|
]).isRequired,
|
|
513
|
-
data : PropTypes.
|
|
336
|
+
data : PropTypes.array,
|
|
514
337
|
columnsWidths : PropTypes.object,
|
|
515
338
|
colsWidths : PropTypes.object,//alias à columnsWidths
|
|
516
339
|
columnWidth: PropTypes.number,
|
|
@@ -537,4 +360,23 @@ TableComponent.popTypes = {
|
|
|
537
360
|
|
|
538
361
|
TableComponent.displayName = "TableComponent";
|
|
539
362
|
|
|
540
|
-
|
|
363
|
+
const TableComponentProvider = React.forwardRef(({children,renderCell,testID,withDatagridContext,getRowKey,filter,data,...props},ref)=>{
|
|
364
|
+
testID = props.testID = defaultStr(testID,"RN_TableComponent");
|
|
365
|
+
const prepatedColumns = usePrepareColumns(props);
|
|
366
|
+
const keyExtractor = typeof getRowKey =='function'? getRowKey : React.getKey;
|
|
367
|
+
const items = React.useMemo(()=>{
|
|
368
|
+
filter = typeof filter =='function'? filter : x=>true;
|
|
369
|
+
return data.filter((i,...rest)=>isObj(i) && !!filter(i,...rest));
|
|
370
|
+
},[data]);
|
|
371
|
+
const getItem = (index)=>items[index]||null;
|
|
372
|
+
return <TableContext.Provider value={{...props,...prepatedColumns,getItem,getRowByIndex:getItem,testID,data,withDatagridContext,keyExtractor,
|
|
373
|
+
renderCell,
|
|
374
|
+
items
|
|
375
|
+
}}>
|
|
376
|
+
<TableComponent {...props} ref={ref}/>
|
|
377
|
+
</TableContext.Provider>
|
|
378
|
+
});
|
|
379
|
+
TableComponentProvider.displayName = "TableComponentProvider";
|
|
380
|
+
TableComponentProvider.propTypes = TableComponent.propTypes;
|
|
381
|
+
|
|
382
|
+
export default TableComponentProvider;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { StyleSheet } from "react-native";
|
|
2
|
+
import {isMobileNative} from "$cplatform";
|
|
3
|
+
|
|
4
|
+
const styles = StyleSheet.create({
|
|
5
|
+
datagrid : {
|
|
6
|
+
flex:1,
|
|
7
|
+
},
|
|
8
|
+
contentContainer : {
|
|
9
|
+
flex:1,
|
|
10
|
+
},
|
|
11
|
+
container : {
|
|
12
|
+
width : '100%',
|
|
13
|
+
minHeight : 300,
|
|
14
|
+
paddingBottom : 10,
|
|
15
|
+
paddingLeft : 0,
|
|
16
|
+
paddingRight : 0,
|
|
17
|
+
flex : 1,
|
|
18
|
+
position : 'relative',
|
|
19
|
+
},
|
|
20
|
+
header2footerContainer:{
|
|
21
|
+
flexDirection : 'column',
|
|
22
|
+
width : '100%',
|
|
23
|
+
height : '100%',
|
|
24
|
+
minHeight : 50,
|
|
25
|
+
},
|
|
26
|
+
headerContainer : {
|
|
27
|
+
width : '100%',
|
|
28
|
+
flexDirection : 'row',
|
|
29
|
+
},
|
|
30
|
+
header: {
|
|
31
|
+
flexDirection: 'row',
|
|
32
|
+
paddingVertical : 7,
|
|
33
|
+
alignItems : 'center',
|
|
34
|
+
width : '100%',
|
|
35
|
+
},
|
|
36
|
+
footerContainer : {
|
|
37
|
+
width : '100%',
|
|
38
|
+
flexDirection : 'row',
|
|
39
|
+
flexWrap : 'wrap',
|
|
40
|
+
},
|
|
41
|
+
footers : {
|
|
42
|
+
minHeight : 40,
|
|
43
|
+
},
|
|
44
|
+
headerItemOrCell : {
|
|
45
|
+
alignItems: 'flex-start',
|
|
46
|
+
alignSelf : 'center',
|
|
47
|
+
height : '100%',
|
|
48
|
+
justifyContent: 'center',
|
|
49
|
+
textAlign : 'left',
|
|
50
|
+
flexWrap : 'wrap',
|
|
51
|
+
paddingHorizontal:5,
|
|
52
|
+
paddingVertical : 0,
|
|
53
|
+
},
|
|
54
|
+
filterCell : {
|
|
55
|
+
alignSelf : "flex-start",
|
|
56
|
+
textAlign : "left",
|
|
57
|
+
paddingHorizontal : 2,
|
|
58
|
+
paddingVertical : 0,
|
|
59
|
+
marginVertical : 0,
|
|
60
|
+
marginHorizontal : 0,
|
|
61
|
+
justifyContent : 'flex-start',
|
|
62
|
+
},
|
|
63
|
+
headerItem: {
|
|
64
|
+
minHeight: 30,
|
|
65
|
+
},
|
|
66
|
+
column : {
|
|
67
|
+
flexDirection : 'row',
|
|
68
|
+
justifyContent : 'center',
|
|
69
|
+
alignItems : 'flex-start',
|
|
70
|
+
},
|
|
71
|
+
row : {
|
|
72
|
+
flexDirection : "row",
|
|
73
|
+
justifyContent : "flex-start",
|
|
74
|
+
alignItems : 'flex-start',
|
|
75
|
+
width : '100%',
|
|
76
|
+
},
|
|
77
|
+
rowNoPadding : {
|
|
78
|
+
paddingHorizontal:0,
|
|
79
|
+
marginHorizontal : 0,
|
|
80
|
+
marginVertical : 0,
|
|
81
|
+
},
|
|
82
|
+
hasNotData : {
|
|
83
|
+
flexDirection : 'column',
|
|
84
|
+
width : '100%',
|
|
85
|
+
justifyContent : 'center',
|
|
86
|
+
alignItems : 'center'
|
|
87
|
+
},
|
|
88
|
+
cell : isMobileNative()? {
|
|
89
|
+
paddingLeft:10,
|
|
90
|
+
paddingRight : 5,
|
|
91
|
+
paddingBottom : 5,
|
|
92
|
+
paddingTop : 5,
|
|
93
|
+
} : {
|
|
94
|
+
paddingLeft: 10,
|
|
95
|
+
paddingTop:5,
|
|
96
|
+
paddingBottom:5,
|
|
97
|
+
paddingRight: 10
|
|
98
|
+
},
|
|
99
|
+
sectionListHeader : {
|
|
100
|
+
paddingVertical : 10,
|
|
101
|
+
paddingHorizontal : 10,
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
export default styles;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const DEFAULT_COLUMN_WIDTH = 60;
|
package/src/context/Provider.js
CHANGED
|
@@ -3,7 +3,7 @@ import appConfig from "$capp/config";
|
|
|
3
3
|
import {MD3LightTheme,MD3DarkTheme} from "react-native-paper";
|
|
4
4
|
import { useMaterial3Theme } from '@pchmn/expo-material3-theme';
|
|
5
5
|
import {colorsAlias,Colors} from "$theme";
|
|
6
|
-
import {isObj,isNonNullString} from "$cutils";
|
|
6
|
+
import {isObj,isNonNullString,defaultStr} from "$cutils";
|
|
7
7
|
import eMainScreens from "$escreens/mainScreens";
|
|
8
8
|
import {ExpoUIContext} from "./hooks";
|
|
9
9
|
import Login from "$eauth/Login";
|
|
@@ -78,8 +78,22 @@ const Provider = ({children,getTableData,navigation,components,convertFiltersToS
|
|
|
78
78
|
}
|
|
79
79
|
theme.fonts = newTheme.fonts;
|
|
80
80
|
const r = typeof extendAppTheme == 'function'? extendAppTheme(theme) : theme;
|
|
81
|
+
const _theme = (isObj(r) ? r : theme);
|
|
82
|
+
const customCSS = _theme.customCSS;
|
|
81
83
|
return {
|
|
82
|
-
...
|
|
84
|
+
..._theme,
|
|
85
|
+
get customCSS(){
|
|
86
|
+
const prevCSS = defaultStr(typeof customCSS ==='function'? customCSS(theme) : customCSS);
|
|
87
|
+
return `
|
|
88
|
+
.virtuoso-table-component,
|
|
89
|
+
.virtuoso-table-component th,
|
|
90
|
+
.virtuoso-table-component tr,
|
|
91
|
+
.virtuoso-table-component td{
|
|
92
|
+
border-collapse : collapse!important;
|
|
93
|
+
}
|
|
94
|
+
${prevCSS}
|
|
95
|
+
`;
|
|
96
|
+
},
|
|
83
97
|
get textFieldMode (){
|
|
84
98
|
/***** possibilité de charger le mode d'affichage par défaut des champs textuels dans le theme de l'application */
|
|
85
99
|
if(typeof theme.textFieldMode =='string' && theme.textFieldMode && modes[theme.textFieldMode]){
|
|
@@ -23,17 +23,18 @@ const AppBarLayout = React.forwardRef(({backActionProps,withDrawer,backAction,ba
|
|
|
23
23
|
goBack();
|
|
24
24
|
return false;
|
|
25
25
|
}
|
|
26
|
-
if(drawerRef
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
drawerRef?.current?.open();
|
|
35
|
-
}
|
|
26
|
+
if(!drawerRef || !drawerRef?.current) return false;
|
|
27
|
+
if(!drawerRef?.current?.isOpen()){
|
|
28
|
+
drawerRef.current.toggle();
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
if(drawerRef?.current?.isMinimized()){
|
|
32
|
+
drawerRef?.current?.restore();
|
|
33
|
+
return false;
|
|
36
34
|
}
|
|
35
|
+
if(!drawerRef?.current?.isPermanent()){
|
|
36
|
+
drawerRef?.current?.toggle();
|
|
37
|
+
}
|
|
37
38
|
return false;
|
|
38
39
|
}}
|
|
39
40
|
ref = {mergedRef}
|