@fto-consult/expo-ui 8.83.3 → 8.84.0
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/auth/utils.js +10 -0
- package/src/components/AppBar/utils.js +3 -5
- package/src/components/Datagrid/Common/Common.js +6 -9
- package/src/components/Drawer/DrawerItems/index.js +5 -5
- package/src/components/Fab/Group.js +2 -3
- package/src/components/Form/Form.js +2 -1
- package/src/components/Form/FormData/FieldContent.js +2 -1
- package/src/components/Form/FormData/FormData.js +2 -1
- package/src/components/TableLink/index.js +4 -7
- package/src/layouts/DatabaseStatistics/index.js +3 -3
- package/src/navigation/Drawer/items/index.js +2 -1
- package/src/navigation/utils.js +3 -2
- package/src/pdf/index.js +3 -8
- package/src/screens/Auth/Profile.js +3 -6
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@fto-consult/expo-ui",
|
3
|
-
"version": "8.
|
3
|
+
"version": "8.84.0",
|
4
4
|
"description": "Bibliothèque de composants UI Expo,react-native",
|
5
5
|
"react-native-paper-doc": "https://github.com/callstack/react-native-paper/tree/main/docs/docs/guides",
|
6
6
|
"scripts": {
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import {isAllowedFromStr} from "$cauth/perms";
|
2
|
+
/***
|
3
|
+
* vérifie si pour la permission perm, l'utilisateur connecté à accès à la resource
|
4
|
+
*/
|
5
|
+
export const isPermAllowed = (perm,...permsArgs)=>{
|
6
|
+
if(typeof perm === 'boolean') return perm;
|
7
|
+
if(typeof perm ==='function' && perm(...permsArgs) === false) return false;
|
8
|
+
if(isNonNullString(perm) && !isAllowedFromStr(perm,...permsArgs)) return false;
|
9
|
+
return true;
|
10
|
+
}
|
@@ -7,8 +7,8 @@ import theme from "$theme"
|
|
7
7
|
import Action from "$ecomponents/Form/Action";
|
8
8
|
import Menu from "$ecomponents/Menu";
|
9
9
|
import Icon,{ MORE_ICON } from "$ecomponents/Icon";
|
10
|
-
import {isAllowedFromStr} from "$cauth/perms";
|
11
10
|
import breakpoints from "$cdimensions/breakpoints";
|
11
|
+
import {isPermAllowed} from "$eauth/utils";
|
12
12
|
|
13
13
|
export const ACTION_ICON_SIZE = 30;
|
14
14
|
|
@@ -104,9 +104,7 @@ export const splitActions = (args)=>{
|
|
104
104
|
let cEl = null;
|
105
105
|
if(!React.isValidElement(act)&& isPlainObj(act)){
|
106
106
|
let {label,perm,text,...action} = act;
|
107
|
-
if(
|
108
|
-
continue;
|
109
|
-
} else if(typeof perm =='function' && perm(args) === false){
|
107
|
+
if(!isPermAllowed(perm,args)) {
|
110
108
|
continue;
|
111
109
|
}
|
112
110
|
action = {...defaultObj(action)};
|
@@ -146,7 +144,7 @@ export const splitActions = (args)=>{
|
|
146
144
|
}
|
147
145
|
if(isPlainObj(cancelButton) && !React.isValidElement(cancelButton)){
|
148
146
|
let {label,perm,text,...action} = cancelButton;
|
149
|
-
|
147
|
+
const canAddCancelBtn = isPermAllowed(perm,{...args,cancelButton,action:cancelButton});
|
150
148
|
if(canAddCancelBtn && (text||label)){
|
151
149
|
action = {...defaultObj(action)};
|
152
150
|
action.label = defaultVal(label,text)
|
@@ -44,10 +44,11 @@ import events from "../events";
|
|
44
44
|
import {MORE_ICON} from "$ecomponents/Icon"
|
45
45
|
import ActivityIndicator from "$ecomponents/ActivityIndicator";
|
46
46
|
import {createTableHeader,fields as pdfFields,pageHeaderMargin,sprintf as pdfSprintf} from "$cpdf";
|
47
|
-
import {
|
47
|
+
import {isMobileNative} from "$cplatform";
|
48
48
|
import { createPDF,getFields as getPdfFields } from '$expo-ui/pdf';
|
49
49
|
import actions from '$cactions';
|
50
50
|
import {printTableData} from "$epdf";
|
51
|
+
import {isPermAllowed} from "$eauth/utils";
|
51
52
|
|
52
53
|
export const TIMEOUT = 100;
|
53
54
|
|
@@ -160,10 +161,6 @@ Object.map(displayTypes,(c,k)=>{
|
|
160
161
|
const dataSourceArgs = {};
|
161
162
|
export const footerFieldName = "dgrid-fters-fields";
|
162
163
|
|
163
|
-
const checkPerm = (perm,args)=>{
|
164
|
-
return typeof perm ==='function'? perm(args) : isNonNullString(perm) ? Auth.isAllowedFromStr(perm) : typeof perm =='boolean'? perm : true;
|
165
|
-
}
|
166
|
-
|
167
164
|
/*****
|
168
165
|
* Pour spécifier qu'un champ du datagrid n'existe pas en bd il s'ufit de suffixer le nom du champ par le suffix : "FoundInDB" et de renseigner false comme valeur
|
169
166
|
de l'objet rowData de cette propriété
|
@@ -206,10 +203,10 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
206
203
|
const disTypes = {};
|
207
204
|
let hasFoundDisplayTypes = false;
|
208
205
|
const pArgs = {context:this,data,props:this.props}
|
209
|
-
const perm =
|
210
|
-
const ePDFIsAllowed = !isMobileNative() &&
|
211
|
-
const eExcelISAllowed =
|
212
|
-
const renderSectionListIsAllowedP =
|
206
|
+
const perm = isPermAllowed(renderChartIsAllowed,pArgs)
|
207
|
+
const ePDFIsAllowed = !isMobileNative() && isPermAllowed(exportToPDFIsAllowed,pArgs);
|
208
|
+
const eExcelISAllowed = isPermAllowed(exportToExcelIsAllowed,pArgs);
|
209
|
+
const renderSectionListIsAllowedP = isPermAllowed(renderSectionListIsAllowed,pArgs);
|
213
210
|
if(typeof customCheckPerms =='function'){
|
214
211
|
customCheckPerms({context:this});
|
215
212
|
}
|
@@ -6,8 +6,7 @@ import DrawerSection from "./DrawerSection"
|
|
6
6
|
import PropTypes from "prop-types";
|
7
7
|
import Divider from "$ecomponents/Divider";
|
8
8
|
import View from "$ecomponents/View";
|
9
|
-
import
|
10
|
-
import { useDrawer } from '../context';
|
9
|
+
import {isPermAllowed} from "$eauth/utils";
|
11
10
|
|
12
11
|
export * from "./utils";
|
13
12
|
|
@@ -23,7 +22,7 @@ const DrawerItemsComponent = React.forwardRef((props,ref)=> {
|
|
23
22
|
const r = React.useMemo(()=>{
|
24
23
|
let items = []
|
25
24
|
const renderExpandableOrSection = ({item,key,items})=>{
|
26
|
-
if(
|
25
|
+
if(!isPermAllowed(item.perm,props)) return null;
|
27
26
|
const {section,items:itx2,...rest} = item;
|
28
27
|
if(section){
|
29
28
|
const sDivider = rest.divider !== false && !hasDivider && items.length ? true : false;
|
@@ -128,7 +127,8 @@ const getDefaultProps = function(item){
|
|
128
127
|
return item;
|
129
128
|
}
|
130
129
|
|
131
|
-
const renderItem = (
|
130
|
+
const renderItem = (args1)=>{
|
131
|
+
let {item,minimized,renderExpandableOrSection,index,key} = args1;
|
132
132
|
key = key||index;
|
133
133
|
if(React.isValidElement(item)){
|
134
134
|
hasDivider = false;
|
@@ -136,7 +136,7 @@ const renderItem = ({item,minimized,renderExpandableOrSection,index,key})=>{
|
|
136
136
|
{item}
|
137
137
|
</React.Fragment>
|
138
138
|
} else {
|
139
|
-
if(
|
139
|
+
if(!isPermAllowed(item.perm,args1)) return null;
|
140
140
|
if(!item.label && !item.text && !item.icon) {
|
141
141
|
if(item.divider === true && !hasDivider){
|
142
142
|
const {divider,...rest} = item;
|
@@ -7,7 +7,7 @@ import {MENU_ICON} from "$ecomponents/Icon";
|
|
7
7
|
import theme,{Colors} from "$theme";
|
8
8
|
import Group from "./GroupComponent";
|
9
9
|
import {Portal} from "react-native-paper";
|
10
|
-
import {
|
10
|
+
import { isPermAllowed } from "$eauth/utils";
|
11
11
|
import { useIsScreenFocused } from '$enavigation/hooks';
|
12
12
|
import { useScreen } from '$econtext/hooks';
|
13
13
|
|
@@ -129,8 +129,7 @@ const FabGroupComponent = React.forwardRef((props,innerRef)=>{
|
|
129
129
|
const a = actionMutator ? actionMutator ({action:act,key:i,isFab:true,fab:true}) : act;
|
130
130
|
if(!isObj(a) || !isNonNullString(a.label)) return null;
|
131
131
|
const {perm,isAllowed,primary,secondary,...restItem} = a;
|
132
|
-
if(
|
133
|
-
if(isNonNullString(perm) && !isAllowedFromStr(perm)) return false;
|
132
|
+
if(!isPermAllowed(perm,{...props,permAction:"fab",action:a}) || !isPermAllowed(isAllowed,{...props,permAction:"fab",action:a})) return false;
|
134
133
|
if(primary){
|
135
134
|
restItem.style = StyleSheet.flatten([restItem.style,{color:theme.colors.onPrimary,backgroundColor:theme.colors.primary}])
|
136
135
|
} else if(secondary){
|
@@ -7,6 +7,7 @@ import { StyleSheet } from "react-native";
|
|
7
7
|
import APP from "$capp/instance";
|
8
8
|
import PropTypes from "prop-types";
|
9
9
|
import View from "$ecomponents/View";
|
10
|
+
import { isPermAllowed } from "$eauth/utils";
|
10
11
|
|
11
12
|
/**** règles d'utilisation :
|
12
13
|
1. les forms doivent toujours avoir un nom : chaine de caractère unique pour l'application et non null
|
@@ -101,7 +102,7 @@ export default class FormComponent extends React.AppComponent {
|
|
101
102
|
Forms.trigger("novalidate",this.props.name,...rest);
|
102
103
|
}
|
103
104
|
render (){
|
104
|
-
if(
|
105
|
+
if(!isPermAllowed(this.props.perm,this.props)){
|
105
106
|
return null;
|
106
107
|
}
|
107
108
|
let {
|
@@ -4,6 +4,7 @@ import {defaultStr,isNonNullString,defaultObj,defaultBool} from "$cutils";
|
|
4
4
|
import getComponentFromType from "./componentsTypes";
|
5
5
|
import appConfig from "$capp/config";
|
6
6
|
import Colors from "$theme/colors";
|
7
|
+
import { isPermAllowed } from "$eauth/utils";
|
7
8
|
|
8
9
|
const FieldContentComponent = React.forwardRef(({field,data,index,fields,formName,onLoopField,fieldProps,backgroundColor,primaryKey:customPrimaryKey,increment,fieldProp,archivable,disabled,windowWidth,responsive,responsiveProps,archived,...props},ref)=>{
|
9
10
|
if(field?.form === false) return null;
|
@@ -19,7 +20,7 @@ const FieldContentComponent = React.forwardRef(({field,data,index,fields,formNam
|
|
19
20
|
if(customPrimaryKey === true){
|
20
21
|
primaryKey = true;
|
21
22
|
}
|
22
|
-
if(form === false || ignore || (
|
23
|
+
if(form === false || ignore || (!isPermAllowed(perm,{...props,field,isFormData:true,index,data,formName}))){
|
23
24
|
return null;
|
24
25
|
}
|
25
26
|
if(rest.nullable === false){
|
@@ -11,6 +11,7 @@ import {handleBeforeSaveCallback} from "./utils";
|
|
11
11
|
import isDbDocEditing,{checkPrimaryKey} from "../utils/isDocEditing";
|
12
12
|
import keyboardShortcuts from "../utils/keyboardShortcuts";
|
13
13
|
import FieldsContent from "./FieldsContent";
|
14
|
+
import { isPermAllowed } from "$eauth/utils";
|
14
15
|
|
15
16
|
export default class FormDataComponent extends AppComponent{
|
16
17
|
constructor(props){
|
@@ -24,7 +25,7 @@ export default class FormDataComponent extends AppComponent{
|
|
24
25
|
value : x=> formName,
|
25
26
|
},
|
26
27
|
isAllowed : {
|
27
|
-
value :
|
28
|
+
value : isPermAllowed(this.props.perm,props),
|
28
29
|
},
|
29
30
|
});
|
30
31
|
}
|
@@ -16,6 +16,8 @@ import Auth from "$cauth";
|
|
16
16
|
import fetch from "$capi/fetch";
|
17
17
|
import useContext from "$econtext/hooks";
|
18
18
|
import TouchableRipple from "$ecomponents/TouchableRipple";
|
19
|
+
import { isPermAllowed } from "$eauth/utils";
|
20
|
+
|
19
21
|
/***** la fonction fetchForeignData permet de spécifier s'il s'agit d'une données de structure où non
|
20
22
|
dans le champ isStructData
|
21
23
|
*/
|
@@ -50,13 +52,8 @@ export const usePrepareProps = (props)=>{
|
|
50
52
|
}
|
51
53
|
const fetchArgs = {type,columnType:type,isStructData,fetch,foreignKeyTable,foreignKeyColumn,data,id};
|
52
54
|
const checkIfAllowed = ()=>{
|
53
|
-
if((
|
54
|
-
|
55
|
-
} else {
|
56
|
-
if(typeof isAllowed ==="function"){
|
57
|
-
if(!isAllowed(args)) return false;
|
58
|
-
} else if(!Auth[isStructData?"isStructDataAllowed":"isTableDataAllowed"]({table:foreignKeyTable,action:'read'})) return false;
|
59
|
-
}
|
55
|
+
if(!isPermAllowed(perm,props) || !isPermAllowed(isAllowed,props)) return false;
|
56
|
+
if((!perm && !isAllowed && perm !== undefined && isAllowed !== undefined) && !Auth[isStructData?"isStructDataAllowed":"isTableDataAllowed"]({table:foreignKeyTable,action:'read'})) return false;
|
60
57
|
return true;
|
61
58
|
}
|
62
59
|
const navigate = (data)=>{
|
@@ -8,6 +8,7 @@ import PropTypes from "prop-types";
|
|
8
8
|
import Auth from "$cauth";
|
9
9
|
import Surface from "$ecomponents/Surface";
|
10
10
|
import { StyleSheet } from "react-native";
|
11
|
+
import {isPermAllowed} from "$eauth/utils";
|
11
12
|
|
12
13
|
export const title = 'Statistiques en BD';
|
13
14
|
export default function DatabaseStatisticScreen ({withScreen,fetchDataProps,itemProps,itemContainerProps,tableFilter,fetchCount,fetchData,title:customTitle,contentProps,containerProps,tables,Component,...props}){
|
@@ -38,10 +39,9 @@ export default function DatabaseStatisticScreen ({withScreen,fetchDataProps,item
|
|
38
39
|
let {containerProps,cellProps,...rDBProps} = dbStatisticsProps;
|
39
40
|
cellProps = Object.assign({},cellProps);
|
40
41
|
containerProps = Object.assign({},containerProps);
|
41
|
-
const chartAllowedPerm = defaultStr(table.chartAllowedPerm);
|
42
42
|
const testID = "RN_DatabaseStatisticsCell_"+index;
|
43
|
-
if(chartAllowedPerm){
|
44
|
-
if(!
|
43
|
+
if(table.chartAllowedPerm !== undefined){
|
44
|
+
if(!isPermAllowed(table.chartAllowedPerm,{table,tables,databaseStatistic:true})) return null;
|
45
45
|
} else if((!Auth.isTableDataAllowed({table:tableName}))) return null;
|
46
46
|
content.push(<Cell elevation = {5} withSurface mobileSize={12} desktopSize={3} tabletSize={6} {...contentProps} testID={testID} {...cellProps} style={[contentProps.style,cellProps.style]} key = {index} >
|
47
47
|
<Surface testID = {testID+"_Surface"} elevation = {5} {...itemContainerProps} {...containerProps} style={[theme.styles.w100,styles.itemContainer,itemContainerProps.style,containerProps.style]}>
|
@@ -16,6 +16,7 @@ import useExpoUI from "$econtext/hooks";
|
|
16
16
|
import Auth,{useIsSignedIn,tableDataPerms} from "$cauth";
|
17
17
|
import {getTableDataListRouteName} from "$enavigation/utils";
|
18
18
|
import {isValidElement,usePrevious} from "$react";
|
19
|
+
import { isPermAllowed } from "$eauth/utils";
|
19
20
|
|
20
21
|
/***** les props supplémentaires à passer aux drawers items d'une table de données sont dans le champ drawerItemProps */
|
21
22
|
const useGetItems = (options)=>{
|
@@ -73,7 +74,7 @@ const useGetItems = (options)=>{
|
|
73
74
|
if(!tableName || table.showInDrawer === false || !Auth.isTableDataAllowed({table:tableName})){
|
74
75
|
return;
|
75
76
|
}
|
76
|
-
if(
|
77
|
+
if(!isPermAllowed(table.perm,{...options,tableName:table,permAction:"drawerItem",tables,table,index})) return;
|
77
78
|
const section = (table.drawerSection).trim();
|
78
79
|
if(!items[section]){
|
79
80
|
if(!sections) sections = Object.keys(items);
|
package/src/navigation/utils.js
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
import {navigate,sanitizeName} from "$cnavigation";
|
5
5
|
import {isNonNullString,defaultStr,defaultObj,isObj} from "$cutils";
|
6
6
|
import appConfig from "$capp/config";
|
7
|
+
import { isPermAllowed } from "$eauth/utils";
|
7
8
|
|
8
9
|
export const tableDataRouteName = 'table-data';
|
9
10
|
|
@@ -35,8 +36,8 @@ const navigateToTableOrStructData = function(tableName,params,actionType){
|
|
35
36
|
let isAllowed = true;
|
36
37
|
actionType = defaultStr(actionType,"tabledata").replaceAll("_","").replaceAll("-","").replaceAll(" ","").toLowerCase();
|
37
38
|
const isTableData = actionType =='tabledata';
|
38
|
-
if(
|
39
|
-
isAllowed =
|
39
|
+
if(perm !== undefined){
|
40
|
+
isAllowed = isPermAllowed(perm,{permAction:"navigate",...params,tableName,table:tableName})
|
40
41
|
} else if(canCheckNavPerms() !== false){
|
41
42
|
if(actionType =='structdata') {
|
42
43
|
isAllowed = Auth.isStructDataAllowed({table:tableName})
|
package/src/pdf/index.js
CHANGED
@@ -10,6 +10,7 @@ import appConfig from "$capp/config";
|
|
10
10
|
import Auth from "$cauth";
|
11
11
|
import DateLib from "$clib/date";
|
12
12
|
import crypToJS from "$clib/crypto-js";
|
13
|
+
import { isPermAllowed } from "$eauth/utils";
|
13
14
|
|
14
15
|
export const QR_CODE_HASH_KEY_PREFIX = defaultStr(appConfig.name).replace(/\s/g, "");
|
15
16
|
export const QR_CODE_HASH_KEY = `${QR_CODE_HASH_KEY_PREFIX}-QR_CODE_HASH_KEY`;//la clé de décryptage du QRCODE
|
@@ -266,14 +267,8 @@ export function printTableData(data,options){
|
|
266
267
|
if(!tablePrint){
|
267
268
|
return Promise.reject({message : `La fonction d'impression n'est pas supportée par la table [${tableText}]`})
|
268
269
|
}
|
269
|
-
if(
|
270
|
-
|
271
|
-
return Promise.reject({message:'Vous n\'etes pas autorisé à imprimer ce type de document'});
|
272
|
-
}
|
273
|
-
} else if(isNonNullString(options.perm)){
|
274
|
-
if(!Auth.isAllowedFromString(options.perm)){
|
275
|
-
return Promise.reject({message:'Vous n\'etes pas autorisé à imprimer ce type de document'});
|
276
|
-
}
|
270
|
+
if((options.perm !== undefined && !isPermAllowed(options.perm,{...options,table,tableObj,permAction:'print',tableName:table,data}))){
|
271
|
+
return Promise.reject({message:'Vous n\'etes pas autorisé à imprimer ce type de document'});
|
277
272
|
} else if(!Auth.isTableDataAllowed({table,action:'print'})){
|
278
273
|
return Promise.reject({message:'Vous n\'etes pas autorisé à imprimer ce type de document'});
|
279
274
|
}
|
@@ -15,7 +15,7 @@ import {isValidUrl} from "$cutils";
|
|
15
15
|
import {screenName} from "./utils";
|
16
16
|
import notify from "$notify";
|
17
17
|
import {getAnimationType,setAnimationType,animationTypes} from "$enavigation/animationTypes"
|
18
|
-
import {
|
18
|
+
import { isPermAllowed } from "$eauth/utils";
|
19
19
|
|
20
20
|
export default function UserProfileScreen({fields,...p}){
|
21
21
|
const {auth:{profilePropsMutator}} = useContext();
|
@@ -49,11 +49,8 @@ export default function UserProfileScreen({fields,...p}){
|
|
49
49
|
const {changeElectronAppUrlPerm} = props;
|
50
50
|
const changeElectronUrl = React.useMemo(()=>{
|
51
51
|
if(!isElectron() || !window?.ELECTRON || typeof ELECTRON?.setAppUrl !=='function' || typeof ELECTRON?.getAppUrl !=='function') return false;
|
52
|
-
if(
|
53
|
-
|
54
|
-
} else if(typeof changeElectronAppUrlPerm =='function'){
|
55
|
-
return !!changeElectronAppUrlPerm(props);
|
56
|
-
}
|
52
|
+
if(!isPermAllowed(changeElectronAppUrlPerm,props)) return false;
|
53
|
+
if(changeElectronAppUrlPerm) return true;
|
57
54
|
return Auth.isMasterAdmin();
|
58
55
|
},[changeElectronAppUrlPerm]);
|
59
56
|
const user = defaultObj(props.user,Auth.getLoggedUser());
|