@fto-consult/expo-ui 6.52.1 → 6.52.3
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 +10 -11
- 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.3",
|
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.
|
73
|
+
"@fto-consult/common": "^3.46.0",
|
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,prepareFetchOptions } 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,15 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
188
189
|
delete opts.page;
|
189
190
|
delete opts.offset;
|
190
191
|
}
|
191
|
-
if(typeof fetcher =='function'){
|
192
|
-
return fetcher(url,opts);
|
193
|
-
}
|
194
|
-
const {url:fUrl,fetcher:cFetcher,...rest} = getFetcherOptions(url,opts);
|
195
192
|
if(showProgressRef.current ===false){
|
196
|
-
|
193
|
+
opts.showError = false;
|
194
|
+
}
|
195
|
+
const {url:fUrl,...rest} = prepareFetchOptions(url,opts);
|
196
|
+
console.log("handling dddfetttcher ",fUrl,url,opts);
|
197
|
+
if(typeof fetcher =='function'){
|
198
|
+
return fetcher(fUrl,rest);
|
197
199
|
}
|
198
|
-
return
|
199
|
-
console.log(e," is swr fetching data");
|
200
|
-
throw e;
|
201
|
-
});
|
200
|
+
return apiFetch(fUrl,rest);
|
202
201
|
},
|
203
202
|
showError : false,
|
204
203
|
swrOptions : getSWROptions(swrConfig.refreshTimeout)
|
@@ -232,7 +231,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
232
231
|
},500);
|
233
232
|
},[error]);
|
234
233
|
const doRefresh = (showProgress)=>{
|
235
|
-
showProgressRef.current = showProgress ? typeof showProgress ==='boolean' :
|
234
|
+
showProgressRef.current = showProgress ? typeof showProgress ==='boolean' : isLoading;
|
236
235
|
refresh();
|
237
236
|
}
|
238
237
|
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)=>{
|