@fto-consult/expo-ui 6.52.1 → 6.52.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/components/Datagrid/Accordion/FilterContent.js +0 -1
- package/src/components/Datagrid/Common/Common.js +7 -0
- package/src/components/Datagrid/SWRDatagrid.js +7 -10
- package/src/components/Datagrid/Table/Filter.js +46 -2
- package/src/components/Datagrid/Table/Filters.js +23 -25
- package/src/components/Datagrid/Table/FiltersMenu.js +26 -15
- package/src/components/Datagrid/Table/hooks.js +2 -1
- package/src/components/Datagrid/Table/styles.js +12 -6
- package/src/components/Filter/index.js +1 -1
- package/src/components/Form/FormData/FieldsContent.js +1 -1
- package/src/components/Portal/Portal.js +1 -1
- package/src/context/query.js +1 -1
- package/src/layouts/Screen/TableData.js +3 -3
- package/src/screens/Auth/PermText.js +1 -1
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@fto-consult/expo-ui",
|
3
|
-
"version": "6.52.
|
3
|
+
"version": "6.52.2",
|
4
4
|
"description": "Bibliothèque de composants UI Expo,react-native",
|
5
5
|
"main": "main",
|
6
6
|
"scripts": {
|
@@ -70,7 +70,7 @@
|
|
70
70
|
"@expo/html-elements": "^0.5.1",
|
71
71
|
"@expo/vector-icons": "^13.0.0",
|
72
72
|
"@faker-js/faker": "^8.0.2",
|
73
|
-
"@fto-consult/common": "^3.45.
|
73
|
+
"@fto-consult/common": "^3.45.10",
|
74
74
|
"@pchmn/expo-material3-theme": "^1.3.1",
|
75
75
|
"@react-native-async-storage/async-storage": "1.18.2",
|
76
76
|
"@react-native-community/datetimepicker": "7.2.0",
|
@@ -1209,8 +1209,12 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
1209
1209
|
toggleFilterColumnVisibility(field,visible){
|
1210
1210
|
if(!isNonNullString(field)) return;
|
1211
1211
|
const filteredColumns = {...this.state.filteredColumns};
|
1212
|
+
if(typeof visible !=='boolean'){
|
1213
|
+
visible = !!!filteredColumns[field];
|
1214
|
+
}
|
1212
1215
|
filteredColumns[field] = visible;
|
1213
1216
|
this.setSessionData("filteredColumns"+this.getSessionNameKey(),filteredColumns);
|
1217
|
+
this.trigger("toggleFilterColumnVisibility",{field,columnField:field,visible});
|
1214
1218
|
return visible;
|
1215
1219
|
}
|
1216
1220
|
|
@@ -2729,6 +2733,9 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
2729
2733
|
getPreparedColumns(){
|
2730
2734
|
return this.preparedColumns;
|
2731
2735
|
}
|
2736
|
+
getColumns(){
|
2737
|
+
return isObj(this.state.columns)? this.state.columns : {};
|
2738
|
+
}
|
2732
2739
|
prepareData(args,cb){
|
2733
2740
|
let {pagination,config,aggregatorFunction:customAggregatorFunction,displayOnlySectionListHeaders:cdisplayOnlySectionListHeaders,data,force,sectionListColumns,sectionListCollapsedStates,updateFooters} = defaultObj(args);
|
2734
2741
|
cb = typeof cb ==='function'? cb : typeof args.cb == 'function'? args.cb : undefined;
|
@@ -14,7 +14,7 @@ import DateLib from "$lib/date";
|
|
14
14
|
import {getFetchOptions} from "$cutils/filters";
|
15
15
|
import {setQueryParams} from "$cutils/uri";
|
16
16
|
import {uniqid} from "$cutils";
|
17
|
-
import { getFetcherOptions } from "$capi/fetch";
|
17
|
+
import apiFetch,{ getFetcherOptions } from "$capi/fetch";
|
18
18
|
import Icon from "$ecomponents/Icon";
|
19
19
|
import Label from "$ecomponents/Label";
|
20
20
|
import { StyleSheet,View } from "react-native";
|
@@ -26,6 +26,7 @@ import PropTypes from "prop-types";
|
|
26
26
|
import {Menu} from "$ecomponents/BottomSheet";
|
27
27
|
import session from "$session";
|
28
28
|
import useContext from "$econtext/hooks";
|
29
|
+
import notify from "$cnotify";
|
29
30
|
|
30
31
|
export const getSessionKey = ()=>{
|
31
32
|
return Auth.getSessionKey("swrDatagrid");
|
@@ -188,17 +189,13 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
188
189
|
delete opts.page;
|
189
190
|
delete opts.offset;
|
190
191
|
}
|
192
|
+
if(showProgressRef.current ===false){
|
193
|
+
opts.showError = false;
|
194
|
+
}
|
191
195
|
if(typeof fetcher =='function'){
|
192
196
|
return fetcher(url,opts);
|
193
197
|
}
|
194
|
-
|
195
|
-
if(showProgressRef.current ===false){
|
196
|
-
rest.showError = false;
|
197
|
-
}
|
198
|
-
return cFetcher(fUrl,rest).catch((e)=>{
|
199
|
-
console.log(e," is swr fetching data");
|
200
|
-
throw e;
|
201
|
-
});
|
198
|
+
return apiFetch(url,opts);
|
202
199
|
},
|
203
200
|
showError : false,
|
204
201
|
swrOptions : getSWROptions(swrConfig.refreshTimeout)
|
@@ -232,7 +229,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
232
229
|
},500);
|
233
230
|
},[error]);
|
234
231
|
const doRefresh = (showProgress)=>{
|
235
|
-
showProgressRef.current = showProgress ? typeof showProgress ==='boolean' :
|
232
|
+
showProgressRef.current = showProgress ? typeof showProgress ==='boolean' : isLoading;
|
236
233
|
refresh();
|
237
234
|
}
|
238
235
|
const canPaginate = ()=>{
|
@@ -1,7 +1,51 @@
|
|
1
1
|
import React from "$react";
|
2
2
|
import View from "$ecomponents/View";
|
3
3
|
import Label from "$ecomponents/Label";
|
4
|
+
import { useDatagrid } from "./hooks";
|
5
|
+
import styles from "./styles";
|
6
|
+
import {defaultStr} from "$cutils";
|
7
|
+
import theme from "$theme";
|
8
|
+
import Filter, {canHandleFilter} from "$ecomponents/Filter";
|
9
|
+
import { getMenuStyle } from "./styles";
|
4
10
|
|
5
|
-
export default function DatagridTableFilterComponent({}){
|
6
|
-
|
11
|
+
export default function DatagridTableFilterComponent({columnField,label,onChange,text,testID,...rest}){
|
12
|
+
const {context,filteredColumns} = useDatagrid();
|
13
|
+
const [visible,setVisible] = React.useState(!!filteredColumns[columnField]);
|
14
|
+
testID = defaultStr(testID,"RN_DatagridTableFilterComponent");
|
15
|
+
React.useEffect(()=>{
|
16
|
+
if(typeof context?.on ==='function'){
|
17
|
+
const onToggleVisibility = ({columnField:cField,visible:nVisible})=>{
|
18
|
+
if(columnField === cField && visible !== nVisible){
|
19
|
+
console.log("toggle ",columnField,nVisible);
|
20
|
+
setVisible(nVisible);
|
21
|
+
}
|
22
|
+
}
|
23
|
+
context.on("toggleFilterColumnVisibility",onToggleVisibility);
|
24
|
+
return ()=>{
|
25
|
+
context.off("toggleFilterColumnVisibility",onToggleVisibility);
|
26
|
+
}
|
27
|
+
}
|
28
|
+
},[context]);
|
29
|
+
label = label || text;
|
30
|
+
return <View testID={testID+"_DatagridFilterTableContainer"} style={[styles.filter,getMenuStyle(),!visible && styles.hidden]}>
|
31
|
+
<View testID={testID+"_DatagridTableFilterContent"} style={[theme.styles.row,theme.styles.alignItemsCenter,theme.styles.justifyContentStart,!visible && styles.hidden]}>
|
32
|
+
{React.isValidElement(label,true) ? <Label numberOfLines={1} style={[styles.filterLabel]}>
|
33
|
+
{label}
|
34
|
+
Un label
|
35
|
+
</Label>:null}
|
36
|
+
<Filter
|
37
|
+
{...rest}
|
38
|
+
withLabel={false}
|
39
|
+
testID={testID+"_DatagridFilterComponent_"+columnField}
|
40
|
+
anchorProps = {{size:20,style:[theme.styles.noMargin,theme.styles.noPadding]}}
|
41
|
+
onChange = {(...args)=>{
|
42
|
+
if(!visible){
|
43
|
+
return;
|
44
|
+
}
|
45
|
+
console.log("calling on change ",args);
|
46
|
+
onChange && onChange(...args);
|
47
|
+
}}
|
48
|
+
/>
|
49
|
+
</View>
|
50
|
+
</View>;
|
7
51
|
}
|
@@ -6,48 +6,46 @@ import { StyleSheet,ScrollView } from "react-native";
|
|
6
6
|
import Label from "$ecomponents/Label";
|
7
7
|
import Filter from "./Filter";
|
8
8
|
import FiltersMenu from "./FiltersMenu";
|
9
|
-
import FilterMenu from "./FilterMenu";
|
10
9
|
import {useDatagrid} from "./hooks";
|
11
10
|
|
12
11
|
export default function DatagridTableFiltersComponent({orOperator,andOperator,testID}){
|
13
12
|
testID = defaultStr(testID,"RN_DatagridTableFiltersComponent")
|
14
|
-
const {
|
13
|
+
const {filters,filteredColumns,filterableColumnsNames} = useDatagrid();
|
14
|
+
const [visibleColumns,context,setVisibleColumns] = React.useState(filteredColumns);
|
15
15
|
const valuesRefs = React.useRef({});
|
16
|
-
|
17
|
-
|
16
|
+
React.useEffect(()=>{
|
17
|
+
if(typeof context?.on ==='function'){
|
18
|
+
const onToggleVisibility = ({columnField,visible})=>{
|
19
|
+
if(visibleColumns[columnField] !== visible){
|
20
|
+
setVisibleColumns({...visibleColumns,[columnField]:visible});
|
21
|
+
}
|
22
|
+
}
|
23
|
+
context.on("toggleFilterColumnVisibility",onToggleVisibility);
|
24
|
+
return ()=>{
|
25
|
+
context.off("toggleFilterColumnVisibility",onToggleVisibility);
|
26
|
+
}
|
27
|
+
}
|
28
|
+
},[context]);
|
29
|
+
const {content} = React.useStableMemo(()=>{
|
18
30
|
const content = [];
|
19
31
|
Object.map(filters,(filter,index)=>{
|
20
32
|
if(isObj(filter)){
|
21
|
-
const {
|
33
|
+
const {filter:isFiltered,...rest} = filter;
|
22
34
|
if(isFiltered === false) return null;
|
23
|
-
const
|
35
|
+
const columnField = defaultStr(filter.field,filter.columnField,String(index));
|
36
|
+
if(!columnField || !visibleColumns[columnField]) return null;
|
24
37
|
content.push(<Filter
|
25
38
|
{...rest}
|
26
|
-
{...(isObj(valuesRefs.current[
|
27
|
-
|
39
|
+
//{...(isObj(valuesRefs.current[columnField]) ? valuesRefs.current[columnField] : {})}
|
40
|
+
columnField={columnField}
|
41
|
+
dynamicRendered={false}
|
28
42
|
orOperator = {defaultBool(orOperator,filter.orOperator,true)}
|
29
43
|
andOperator = {defaultBool(andOperator,filter.andOperator,true)}
|
30
|
-
onChange = {(arg)=>{
|
31
|
-
if(!arg.action && !arg.operator || !arg.field) return;
|
32
|
-
const canHandle = canHandleFilter(arg);
|
33
|
-
valuesRefs.current[key] = arg;
|
34
|
-
if(filteredRef.current[key] !== canHandle){
|
35
|
-
if(canHandle){
|
36
|
-
canHandlerFilterRef.current++;
|
37
|
-
} else {
|
38
|
-
canHandlerFilterRef.current = Math.max(0,canHandlerFilterRef.current-1);
|
39
|
-
}
|
40
|
-
}
|
41
|
-
filteredRef.current[key] = canHandle;
|
42
|
-
if(onChange){
|
43
|
-
onChange(arg);
|
44
|
-
}
|
45
|
-
}}
|
46
44
|
/>)
|
47
45
|
}
|
48
46
|
})
|
49
47
|
return {content};
|
50
|
-
},[
|
48
|
+
},[visibleColumns])
|
51
49
|
return <ScrollView horizontal testID={testID+"_FiltersScrollView"}>
|
52
50
|
<View testID={testID} style = {[theme.styles.row,styles.container,theme.styles.rowWrap,theme.styles.justifyStart,theme.styles.alignItemsCenter]}>
|
53
51
|
{<FiltersMenu/>}
|
@@ -7,36 +7,47 @@ import theme from "$theme";
|
|
7
7
|
import Label from "$ecomponents/Label";
|
8
8
|
import React from "$react";
|
9
9
|
import { getMenuStyle } from "./styles";
|
10
|
+
import BottomSheetMenu from "$ecomponents/BottomSheet/Menu";
|
10
11
|
|
11
12
|
export default function DatagridFiltersMenuComponent({testID,...props}){
|
12
|
-
const {filteredColumns,filterableColumnsNames
|
13
|
+
const {filteredColumns,columns,context,filterableColumnsNames} = useDatagrid();
|
14
|
+
const [visibleMenus,setVisibleMenus] = React.useState(filteredColumns);
|
13
15
|
const isFiltered = !!Object.size(filteredColumns,true);
|
14
16
|
testID = defaultStr(testID,"RN_DatagridFiltersMenuComponent")
|
15
|
-
console.log(props," is props heeein");
|
16
17
|
const items = React.useStableMemo(()=>{
|
17
18
|
const items = [];
|
18
|
-
|
19
|
-
Object.map(filterableColumnsNames,(field)=>{
|
20
|
-
|
19
|
+
if(!columns) return items;
|
20
|
+
Object.map(filterableColumnsNames,(field,i)=>{
|
21
|
+
const column = columns[field];
|
22
|
+
if(!isObj(column)) return;
|
23
|
+
const filterKey = defaultStr(column.field,column.name,i);
|
24
|
+
items.push({
|
25
|
+
...column,
|
26
|
+
icon : !!visibleMenus[filterKey] ? "check":undefined,
|
27
|
+
items : undefined,
|
28
|
+
onPress : (e)=>{
|
29
|
+
const visible = !!visibleMenus[filterKey];
|
30
|
+
const nVisible = context?.toggleFilterColumnVisibility? context.toggleFilterColumnVisibility(filterKey,!!!visible) : visible;
|
31
|
+
if(nVisible !== visible){
|
32
|
+
setVisibleMenus({...visibleMenus,[filterKey]:nVisible});
|
33
|
+
}
|
34
|
+
}
|
35
|
+
})
|
21
36
|
});
|
22
|
-
return;
|
23
|
-
|
24
|
-
|
25
|
-
filterKey={key}
|
26
|
-
{...filter}
|
27
|
-
context={context}
|
28
|
-
filteredColumns={filteredColumns}
|
29
|
-
/>)
|
30
|
-
},[filterableColumnsNames]);
|
31
|
-
return <Menu
|
37
|
+
return items;
|
38
|
+
},[filterableColumnsNames,visibleMenus]);
|
39
|
+
return <BottomSheetMenu
|
32
40
|
testID={testID}
|
41
|
+
title = {"Filtres"}
|
33
42
|
{...props}
|
43
|
+
items = {items}
|
34
44
|
anchor={(p)=>{
|
35
45
|
return <Pressable {...p} testID={testID+"_FilterPressableContainer"} style={[theme.styles.row,theme.styles.justifyContentStart,theme.styles.alignItemsCenter,getMenuStyle()]}>
|
36
46
|
<Icon
|
37
47
|
name={isFiltered?"filter-menu":"filter-plus"}
|
38
48
|
primary = {isFiltered}
|
39
49
|
size={20}
|
50
|
+
style={[theme.styles.noPadding,theme.styles.noMargin]}
|
40
51
|
/>
|
41
52
|
<Label primary={isFiltered} textBold={isFiltered}>Filtres</Label>
|
42
53
|
</Pressable>
|
@@ -4,5 +4,6 @@ export const useDatagrid = ()=>{
|
|
4
4
|
const visible = context && typeof context?.canShowFilters =='function' && context.canShowFilters()|| false;
|
5
5
|
const isLoading = context && context.isLoading() || false;
|
6
6
|
const r = typeof context?.getPreparedColumns =='function'? context?.getPreparedColumns() : {};
|
7
|
-
|
7
|
+
const columns = typeof context?.getColumns =='function' && context.getColumns() || {}
|
8
|
+
return {...r,visible,isLoading,context,columns};
|
8
9
|
}
|
@@ -3,14 +3,20 @@ import theme from '$theme';
|
|
3
3
|
|
4
4
|
const styles = StyleSheet.create({
|
5
5
|
menuItem : {
|
6
|
-
borderRadius :
|
6
|
+
borderRadius : 7,
|
7
|
+
margin : 5,
|
8
|
+
paddingHorizontal : 10,
|
9
|
+
paddingVertical : 2,
|
10
|
+
},
|
11
|
+
hidden : {
|
12
|
+
display : "none",
|
13
|
+
opacity : 0,
|
14
|
+
},
|
15
|
+
filterLabel : {
|
16
|
+
fontSize:11,
|
7
17
|
}
|
8
18
|
});
|
9
19
|
|
10
|
-
export const getMenuStyle = (style)=>([
|
11
|
-
styles.menuItem,
|
12
|
-
{backgroundColor:theme.surfaceBackground},
|
13
|
-
style,
|
14
|
-
]);
|
20
|
+
export const getMenuStyle = (style)=>([styles.menuItem,{backgroundColor:theme.colors.surface},style]);
|
15
21
|
|
16
22
|
export default styles;
|
@@ -222,7 +222,7 @@ export default class Filter extends AppComponent {
|
|
222
222
|
}
|
223
223
|
}
|
224
224
|
}
|
225
|
-
this.props.onChange({...this.getStateValues(),value,field:this.props.field,action,operator,selector,originAction,context:this});
|
225
|
+
this.props.onChange({...this.getStateValues(),value,field:this.props.field,columnField:this.props.field,action,operator,selector,originAction,context:this});
|
226
226
|
}
|
227
227
|
}
|
228
228
|
componentDidUpdate (){
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import React from "$react";
|
2
2
|
import Divider from "$ecomponents/Divider";
|
3
|
-
import {isObj,isNonNullString,defaultStr,defaultObj} from "$
|
3
|
+
import {isObj,isNonNullString,defaultStr,defaultObj} from "$cutils";
|
4
4
|
import {flattenStyle,Colors} from "$theme";
|
5
5
|
import FieldContent from "./FieldContent";
|
6
6
|
|
@@ -4,7 +4,7 @@
|
|
4
4
|
@see : https://github.com/gorhom/react-native-portal
|
5
5
|
*/
|
6
6
|
import { memo, useCallback, useEffect, useMemo, useRef } from 'react';
|
7
|
-
import {uniqid} from "$
|
7
|
+
import {uniqid} from "$cutils";
|
8
8
|
import { usePortal } from './hooks';
|
9
9
|
|
10
10
|
const PortalComponent = ({
|
package/src/context/query.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import {isNonNullString,isObj,extendObj
|
1
|
+
import {isNonNullString,isObj,extendObj} from "$cutils";
|
2
2
|
import { useQuery as useRQuery, useMutation as RQUseMutation, useQueryClient } from "@tanstack/react-query";
|
3
3
|
import { getFetcherOptions as apiGetFetcherOptions } from '$capi';
|
4
4
|
|
@@ -425,7 +425,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
425
425
|
if(hasTabs){
|
426
426
|
if(isMobOrTab){
|
427
427
|
renderingTabsProps.firstTab = <Tab.Item testID={testID+"_MainTab"} label={"Principal"} {...firstTabProps} key={tabKey}>
|
428
|
-
<View testID={testID+"_MainTab_Content"} {...contentProps} style={[styles.
|
428
|
+
<View testID={testID+"_MainTab_Content"} {...contentProps} style={[styles.noMargin,contentProps.style,styles.h100,styles.noPadding]}>
|
429
429
|
{header}
|
430
430
|
{content}
|
431
431
|
</View>
|
@@ -435,7 +435,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
435
435
|
}
|
436
436
|
const ct = renderTabsContent(renderingTabsProps);
|
437
437
|
if(isMobOrTab && ct){
|
438
|
-
contentProps.style = [contentProps.style,styles.
|
438
|
+
contentProps.style = [contentProps.style,styles.noMargin,styles.noPadding,styles.content]
|
439
439
|
mainContent = ct;
|
440
440
|
} else {
|
441
441
|
mainContent = <View {...contentProps} testID={testID+"_ContentContainer"} style={[styles.container,styles.noPadding,contentProps.style]}>
|
@@ -907,7 +907,7 @@ const styles = StyleSheet.create({
|
|
907
907
|
paddingHorizontal : 0,
|
908
908
|
paddingVertical : 0,
|
909
909
|
},
|
910
|
-
|
910
|
+
noMargin : {
|
911
911
|
margin : 0,
|
912
912
|
marginVertical : 0,
|
913
913
|
marginHorizontal : 0,
|
@@ -13,7 +13,7 @@ const PermText = React.forwardRef(({isUserMasterAdmin,disabled,assignPerm,testID
|
|
13
13
|
testID = {testID}
|
14
14
|
disabled = {disabled || isUserMasterAdmin}
|
15
15
|
defaultValue = {checked || isUserMasterAdmin?1 : 0}
|
16
|
-
style = {[theme.styles.noPadding,theme.styles.
|
16
|
+
style = {[theme.styles.noPadding,theme.styles.noMargin,labelStyle !== false && styles.checkbox]}
|
17
17
|
labelStyle = {[labelStyle !== false && styles.label,labelStyle && labelStyle]}
|
18
18
|
label = {defaultVal(label,text)}
|
19
19
|
onPress = {(args)=>{
|