@fto-consult/expo-ui 4.0.4 → 4.1.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fto-consult/expo-ui",
3
- "version": "4.0.4",
3
+ "version": "4.1.0",
4
4
  "description": "Bibliothèque de composants UI Expo,react-native",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -61,7 +61,7 @@
61
61
  "@emotion/native": "^11.10.0",
62
62
  "@expo/html-elements": "^0.2.0",
63
63
  "@expo/vector-icons": "^13.0.0",
64
- "@fto-consult/common": "^2.17.2",
64
+ "@fto-consult/common": "^2.18.0",
65
65
  "@gorhom/portal": "^1.0.14",
66
66
  "@react-native-async-storage/async-storage": "~1.17.3",
67
67
  "@react-native-community/datetimepicker": "6.5.2",
@@ -50,7 +50,7 @@ const TableDataSelectField = React.forwardRef(({foreignKeyColumn,foreignKeyTable
50
50
  }
51
51
  }
52
52
  const isMounted = React.useIsMounted();
53
- const showAdd = isFilter || !foreignKeyTable ? false : React.useRef(Auth.isTableDataAllowed({foreignKeyTable,action:'create'}) ? defaultVal(props.showAdd,props.showAddBtn,true) : false).current;
53
+ const showAdd = isFilter || !foreignKeyTable ? false : React.useRef(Auth.isTableDataAllowed({table:foreignKeyTable,action:'create'}) ? defaultVal(props.showAdd,props.showAddBtn,true) : false).current;
54
54
  const [state,setState] = React.useState({
55
55
  items : [],isLoading : true,
56
56
  });
@@ -214,7 +214,6 @@ export default class TableDataScreenComponent extends FormDataScreen{
214
214
  onKeyEvent,
215
215
  canMakePhoneCall : customCanMakePhoneCall,
216
216
  makePhoneCallProps : customMakePhoneCallProps,
217
- beforeSave,
218
217
  closeOnSave,closeAfterSave,
219
218
  table : cTable,
220
219
  onSave,
@@ -349,6 +348,13 @@ export default class TableDataScreenComponent extends FormDataScreen{
349
348
  formProps.onKeyEvent = this.onKeyEvent.bind(this);
350
349
  rActionsArg.elevation = typeof rActionsArg.contentProps.elevation ==="number"? contentProps.elevation : typeof elevation == 'number' ? elevation : 5;
351
350
  rActionsArg.formProps = formProps;
351
+ if(typeof this.props.getComponentProps =='function'){
352
+ const p = this.props.getComponentProps(rActionsArg);
353
+ if(isObj(p)){
354
+ this.currentRenderingProps = p;
355
+ return p;
356
+ }
357
+ }
352
358
  return rActionsArg;
353
359
  }
354
360
  renderTabs(args){
@@ -17,7 +17,8 @@ export const navigateToTableData = function(tableName,params,actionType){
17
17
  if(!tableName) return;
18
18
  const {perm} = params;
19
19
  let isAllowed = true;
20
- const isTableData = actionType =='table_data';
20
+ actionType = defaultStr(actionType,"tabledata").replaceAll(" ","").toLowerCase();
21
+ const isTableData = actionType =='tabledata';
21
22
  if(isNonNullString(perm)){
22
23
  isAllowed = Auth.isAllowedFromStr(perm)
23
24
  } else if(actionType =='struct_data') {
@@ -0,0 +1,195 @@
1
+ import PermText from "./PermText";
2
+ import React from "$react";
3
+ import Expandable from "$ecomponents/Expandable";
4
+ import {defaultObj,defaultStr,arrayValueExists,isNonNullString,defaultVal} from "$cutils";
5
+ import PropTypes from "prop-types";
6
+ import {hasResource} from "./utils";
7
+ import { StyleSheet } from "react-native";
8
+ import View from "$ecomponents/View";
9
+ import {Cell} from "$ecomponents/Grid";
10
+
11
+ const PermLine = ({text,cellProps,isUserMasterAdmin,withGrid,defaultActions,resource,perms:cPerms,disabled,allPerms,table,index,onChange,keyname,actions,testID,...rest})=>{
12
+ const [state,setState] = React.useState({
13
+ data : defaultObj(rest.data),
14
+ expanded : defaultBool(rest.expanded,false)
15
+ });
16
+ allPerms = defaultObj(allPerms);
17
+ cellProps = defaultObj(cellProps);
18
+ testID = defaultStr(testID,"RN_AuthPermLineComponent_"+index);
19
+ table = defaultStr(table).toLowerCase();
20
+ resource = resource.toLowerCase();
21
+ if(!table) {
22
+ console.error("table non spécifiée pour la perm line ",table,rest);
23
+ return null;
24
+ }
25
+ cPerms = defaultObj(cPerms);;
26
+ const perms = React.useMemo(()=>{
27
+ const perms = defaultObj(cPerms);
28
+ if(perms.defaultActions !== false || (isObj(perms[resource]) && Object.size(perms[resource],true)>0)){
29
+ const _acts = perms.defaultActions !== false ? {...defaultActions} : {};
30
+ Object.map(_acts,(a,aa)=>{
31
+ const aa2 = a && a.alias && typeof a.alias =='string' && a.alias;
32
+ if(perms[aa] === false || perms[aa.toLowerCase()+'Action'] === false || (aa2 && (perms[aa2] === false || perms[aa2.toLowerCase()+'Action'] === false))){
33
+ delete _acts[aa];
34
+ }
35
+ });
36
+ if(isObj(perms[resource])){
37
+ perms[resource] = {
38
+ ...perms[resource],
39
+ actions : {
40
+ ..._acts,
41
+ ...defaultObj(perms[resource].actions)
42
+ }
43
+ }
44
+ } else {
45
+ perms[resource] = {
46
+ text,
47
+ actions : _acts
48
+ }
49
+ }
50
+ }
51
+ return perms;
52
+ },[cPerms.defaultActions,cPerms[resource]])
53
+ let allChecked = true;
54
+ isUserMasterAdmin = !!isUserMasterAdmin;
55
+ let checked = isUserMasterAdmin;
56
+ const onToggleSingle = ({resource,checked,action})=>{
57
+ if(isUserMasterAdmin || !isNonNullString(action) || !isNonNullString(resource) || !isNonNullString(allPerms[resource])){
58
+ return;
59
+ }
60
+ const data = {...state.data};
61
+ const allAction = defaultStr(allPerms[resource]);
62
+ if(allAction == "all"){
63
+ if(checked){
64
+ data[resource] = allAction;
65
+ } else delete data[resource];
66
+ } else {
67
+ data[resource] = defaultStr(data[resource]).toLowerCase();
68
+ let spl = data[resource].split("2");
69
+ if(checked){
70
+ if(action !== 'read' && arrayValueExists(allAction.toLowerCase().split("2"),'read') && !arrayValueExists(spl,'read')){
71
+ spl.push('read');
72
+ }
73
+ if(!arrayValueExists(spl,action,true)){
74
+ spl.push(action);
75
+ }
76
+ } else {
77
+ let s1 = [];
78
+ for(let i in spl){
79
+ if(spl[i].toLowerCase() !== action.toLowerCase()){
80
+ s1.push(spl[i]);
81
+ }
82
+ }
83
+ spl = s1;
84
+ }
85
+ if(spl.length>0){
86
+ data[resource] = spl.join("2").ltrim("2").rtrim("2");
87
+ } else delete data[resource];
88
+ }
89
+ setState({...state,data});
90
+ }
91
+ const toggleAll = (arg)=>{
92
+ const {checked} = arg;
93
+ const data = {...state.data};
94
+ for(let i in allPerms){
95
+ if(hasResource(i,resource)){
96
+ if(!checked){
97
+ delete data[i];
98
+ } else {
99
+ data[i] = allPerms[i];
100
+ }
101
+ }
102
+ }
103
+ setState({...state,data});
104
+ }
105
+ React.useEffect(()=>{
106
+ if(onChange){
107
+ onChange({data:state.data,resource,table});
108
+ }
109
+ },[state.data])
110
+ const content = [];
111
+ Object.map(perms,(perm,i)=>{
112
+ const pText = defaultStr(perm.text,perm.label);
113
+ if(!isObj(perm.actions)){
114
+ if(!isNonNullString(pText)) return null;
115
+ allPerms[i] = "all";
116
+ checked = isUserMasterAdmin? true : isNonNullString(state.data[i]);
117
+ if(!checked){
118
+ allChecked = false;
119
+ }
120
+ content.push(<PermText isUserMasterAdmin={isUserMasterAdmin} key = {i} table={table} tooltip={defaultStr(perm.tooltip,perm.title,perm.desc)} onToggle={onToggleSingle} text={pText} checked ={checked} resource={i} action ={'all'}/>);
121
+ return;
122
+ }
123
+ allPerms[i] = "";
124
+ const splitP = defaultStr(state.data[i]).toLowerCase().split("2");
125
+ const pContent = []
126
+ const hasS = isNonNullString(text) && isNonNullString(pText) && pText.toLowerCase() != text.toLowerCase()
127
+ Object.map(perm.actions,(p,j)=>{
128
+ if(!isObj(p) || !isNonNullString(p.text)) return null;
129
+ allPerms[i] = (isNonNullString(allPerms[i])?(allPerms[i]+"2"):"")+j;
130
+ checked = isUserMasterAdmin? true : arrayValueExists(splitP,j,true);
131
+ if(!checked){
132
+ allChecked = false;
133
+ }
134
+ pContent.push(<PermText labelStyle ={hasS? styles.permChildren : undefined} isUserMasterAdmin={isUserMasterAdmin} key={j} table={table} onToggle={onToggleSingle} tooltip={defaultStr(p.tooltip,p.title,p.desc)} text = {p.text} checked ={checked} actions={perm.actions} resource={i} action ={j}/>)
135
+ });
136
+ if(pContent.length){
137
+ content.push(<View key={i} testID={testID+"_Content_"+i}>
138
+ {hasS ? <Label testID={testID+'_Label'}>{pText}</Label> : null}
139
+ {pContent}
140
+ </View>)
141
+ }
142
+
143
+ });
144
+ return <Cell testID={testID+"_Cell"} tabletSize={6} desktopSize={4} phoneSize={12} {...cellProps}>
145
+ <Expandable
146
+ expandedIcon ={'chevron-right'}
147
+ unexpandedIcon = {'chevron-down'}
148
+ elevation = {5}
149
+ {...rest}
150
+ testID = {testID}
151
+ expandIconPosition = {"left"}
152
+ onPress={(e)=>{
153
+ setState({...state,expanded:!state.expanded})
154
+ }}
155
+ contentProps = {{style:styles.expandableContent}}
156
+ expanded={state.expanded}
157
+ title = {
158
+ <PermText
159
+ table={table}
160
+ labelStyle = {false}
161
+ checked = {allChecked}
162
+ disabled = {disabled}
163
+ resource={resource} action={allPerms[resource]}
164
+ text={text}
165
+ testID = {testID+"_"+table}
166
+ isUserMasterAdmin = {isUserMasterAdmin}
167
+ onToggle = {toggleAll}
168
+ />
169
+ }
170
+ >
171
+ {content}
172
+ </Expandable>
173
+ </Cell>
174
+ }
175
+
176
+
177
+ PermLine.propTypes = {
178
+ text : PropTypes.string,
179
+ resource : PropTypes.string.isRequired,
180
+ cellProps : PropTypes.object,//les props du composant Cell, wrappeur au composant PermLine
181
+ defaultActions : PropTypes.object.isRequired,//les actions par défault
182
+ }
183
+
184
+ const styles = StyleSheet.create({
185
+ expandableContent : {
186
+ paddingLeft : 30,
187
+ },
188
+ permChildren : {
189
+ paddingLeft : 20,
190
+ },
191
+ });
192
+
193
+ PermLine.displayName = "AuthPermLineComponent";
194
+
195
+ export default PermLine;
@@ -1,238 +1,35 @@
1
- import tables from "$database/data/tables";
2
- import Checkbox from "$components/Checkbox";
3
1
  import React from "$react";
4
2
  import { StyleSheet } from "react-native";
5
- import {defaultVal,defaultObj,defaultBool,arrayValueExists} from "$utils";
3
+ import {defaultObj,extendObj} from "$utils";
6
4
  import Auth from "$cauth";
7
- import Label from "$ecomponents/Label";
8
- import View from "$ecomponents/View";
9
5
  import Expandable from "$ecomponents/Expandable";
10
6
  import PropTypes from "prop-types";
11
- import Grid,{Cell} from "$components/Grid";
12
7
  import theme from "$theme";
13
- import appConfig from "$capp/config";
8
+ import {defaultActions as mDefaultAction,hasResource} from "./utils";
9
+ import PermLine from "./PermLine";
10
+ import Grid from "$ecomponents/Grid";
14
11
 
15
-
16
- let allPerms = {};
17
- const defaultActions = {
18
- create : {
19
- text : 'Créer'
20
- },
21
- update : {
22
- text : 'Modifier'
23
- },
24
- delete : {
25
- text : 'Supprimer'
26
- },
27
- read : {
28
- text : 'Consulter',
29
- },
30
- }
31
- const expandIconProps = {
32
- //size : 20,
33
- }
34
- export const PermText = (props)=>{
35
- const {isMasterAdmin} = props;
36
- const {user} = props;
37
- const isAllowed = isMasterAdmin ? true : React.useRef(Auth.isTableDataAllowed({table:'users',user,action:'assignPerms'})).current;
38
- const {text,label,checked,labelStyle,table,type,onToggle,actions,action,resource,tooltip} = props;
39
- return <Checkbox
40
- title = {tooltip}
41
- disabled = {!isAllowed || isMasterAdmin}
42
- defaultValue = {checked || isMasterAdmin?1 : 0}
43
- style = {[theme.styles.noPadding,theme.styles.noMarging,labelStyle !== false && styles.checkbox]}
44
- labelStyle = {[labelStyle !== false && styles.label,labelStyle && labelStyle]}
45
- label = {defaultVal(label,text)}
46
- onPress = {(args)=>{
47
- React.stopEventPropagation(args?.event);
48
- if(onToggle){
49
- onToggle({...args,checked:!!!checked,resource,actions,action,table,type})
50
- }
51
- return false;
52
- }}
53
- />
54
- }
55
-
56
-
57
-
58
- export const PermLine = (props)=>{
59
- const [state,setState] = React.useState({
60
- data : defaultObj(props.data),
61
- expanded : defaultBool(props.expanded,false)
62
- });
63
- let {text,user,isMasterAdmin,perms,table,index,onChange,type,keyname,actions,testID,...rest} = props;
64
- testID = defaultStr(testID,"RN_AuthPermLineComponent_"+index);
65
- table = defaultStr(table).toLowerCase();
66
- type = defaultStr(type).toLowerCase();
67
- perms = Object.assign({},perms);
68
- let resource = undefined;
69
- if(arrayValueExists(['table','structdata','struct_data'],type)){
70
- if(type === 'struct_data'){
71
- type = 'structdata';
72
- }
73
- resource = type+"/"+table;
74
- if(perms.defaultActions !== false || (isObj(perms[resource]) && Object.size(perms[resource],true)>0)){
75
- let _acts = {};
76
- if(perms.defaultActions !== false) {
77
- _acts = {...defaultActions};
78
- }
79
- if(perms[resource]){
80
- perms[resource] = {
81
- text,
82
- actions : {..._acts,...defaultObj(perms[resource])}
83
- }
84
- } else {
85
- perms[resource] = {
86
- text,
87
- actions : {..._acts,...defaultObj(perms[resource])}
88
- }
89
- }
90
- }
91
- }
92
- let allChecked = true;
93
- let checked = isMasterAdmin;
94
- const onToggleSingle = ({resource,checked,action})=>{
95
- if(isMasterAdmin || !isNonNullString(action) || !isNonNullString(resource) || !isNonNullString(allPerms[resource])){
96
- return;
97
- }
98
- const data = {...state.data};
99
- const allAction = defaultStr(allPerms[resource]);
100
- if(allAction == "all"){
101
- if(checked){
102
- data[resource] = allAction;
103
- } else delete data[resource];
104
- } else {
105
- data[resource] = defaultStr(data[resource]).toLowerCase();
106
- let spl = data[resource].split("2");
107
- if(checked){
108
- if(action !== 'read' && arrayValueExists(allAction.toLowerCase().split("2"),'read') && !arrayValueExists(spl,'read')){
109
- spl.push('read');
110
- }
111
- if(!arrayValueExists(spl,action,true)){
112
- spl.push(action);
113
- }
114
- } else {
115
- let s1 = [];
116
- for(let i in spl){
117
- if(spl[i].toLowerCase() !== action.toLowerCase()){
118
- s1.push(spl[i]);
119
- }
120
- }
121
- spl = s1;
122
- }
123
- if(spl.length>0){
124
- data[resource] = spl.join("2").ltrim("2").rtrim("2");
125
- } else delete data[resource];
126
- }
127
- setState({...state,data});
128
- if(onChange){
129
- onChange({data,resource,table,type});
130
- }
131
- }
132
- const toggleAll = (arg)=>{
133
- if(!isNonNullString(type) || !isNonNullString(table) || !isNonNullString(resource)){
134
- return;
135
- }
136
- const {checked} = arg;
137
- const data = {...state.data};
138
- for(let i in allPerms){
139
- if(i.toLowerCase().startsWith(resource)){
140
- if(!checked){
141
- delete data[i];
142
- } else {
143
- data[i] = allPerms[i];
144
- }
145
- }
146
- }
147
- setState({...state,data});
148
- if(onChange){
149
- onChange({data,resource,table,type});
150
- }
151
- }
152
- const content = [];
153
- Object.map(perms,(perm,i)=>{
154
- const pText = defaultStr(perm.text,perm.label);
155
- if(!isObj(perm.actions)){
156
- if(!isNonNullString(pText)) return null;
157
- allPerms[i] = "all";
158
- checked = isMasterAdmin? true : isNonNullString(state.data[i]);
159
- if(!checked){
160
- allChecked = false;
161
- }
162
- content.push(<PermText user={user} isMasterAdmin={isMasterAdmin} key = {i} table={table} tooltip={defaultStr(perm.tooltip,perm.title,perm.desc)} onToggle={onToggleSingle} text={pText} checked ={checked} resource={i} action ={'all'}/>);
163
- return;
164
- }
165
- allPerms[i] = "";
166
- const splitP = defaultStr(state.data[i]).toLowerCase().split("2");
167
- const pContent = []
168
- Object.map(perm.actions,(p,j)=>{
169
- if(!isObj(p) || !isNonNullString(p.text)) return null;
170
- allPerms[i] = (isNonNullString(allPerms[i])?(allPerms[i]+"2"):"")+j;
171
- checked = isMasterAdmin? true : arrayValueExists(splitP,j,true);
172
- if(!checked){
173
- allChecked = false;
174
- }
175
- pContent.push(<PermText user={user} labelStyle ={styles.permChildren} isMasterAdmin={isMasterAdmin} key={j} table={table} onToggle={onToggleSingle} tooltip={defaultStr(p.tooltip,p.title,p.desc)} text = {p.text} checked ={checked} actions={perm.actions} resource={i} action ={j}/>)
176
- });
177
- if(pContent.length){
178
- const hasS = isNonNullString(text) && isNonNullString(pText) && pText.toLowerCase() != text.toLowerCase()
179
- content.push(<View key={i} testID={testID+"_Content_"+i}>
180
- {hasS ? <Label testID={testID+'_Label'}>{pText}</Label> : null}
181
- {pContent}
182
- </View>)
183
- }
184
-
185
- });
186
- return <Expandable
187
- expandIconProps = {expandIconProps}
188
- expandedIcon ={'chevron-right'}
189
- unexpandedIcon = {'chevron-down'}
190
- {...defaultObj(rest)}
191
- testID = {testID}
192
- expandIconPosition = {"left"}
193
- onPress={(e)=>{
194
- setState({...state,expanded:!state.expanded})
195
- }}
196
- contentProps = {{style:styles.expandableContent}}
197
- expanded={state.expanded}
198
- title = {
199
- <PermText
200
- user={user}
201
- table={table}
202
- labelStyle = {false}
203
- checked = {allChecked}
204
- type={type} resource={resource} action={allPerms[resource]}
205
- text={text}
206
- testID = {testID+"_"+table}
207
- isMasterAdmin = {isMasterAdmin}
208
- onToggle = {toggleAll}
209
- />
210
- }
211
- >
212
- {content}
213
- </Expandable>
214
- }
215
-
216
-
217
- PermLine.propTypes = {
218
- text : PropTypes.string.isRequired,
219
- type : PropTypes.string.isRequired,
220
- }
221
-
222
- const PermLines = React.forwardRef((props,ref)=>{
223
- const isMasterAdmin = defaultBool(props.isMasterAdmin,false);
224
- const {user} = props;
225
- const dataRef = React.useRef(defaultObj(props.perms,defaultObj(props.data).perms));
226
- let {testID} = props;
12
+ const PermLines = React.forwardRef(({user,gridProps,defaultActions:cDefaultActions,disabled,isUserMasterAdmin:cIsMasterAdmin,permLineProps,cellProps,containerProps,style,tablePermPrefix,tables,title,testID,perms,onChange:cOnChange,...props},ref)=>{
13
+ const isUserMasterAdmin = !!cIsMasterAdmin;
14
+ user = defaultObj(user,Auth.getLoggedUser());
15
+ gridProps = defaultObj(gridProps);
16
+ containerProps = defaultObj(containerProps);
17
+ containerProps.style = [theme.styles.w100,containerProps.style]
18
+ cellProps = defaultObj(cellProps);
19
+ permLineProps = defaultObj(permLineProps);
20
+ const allPerms = React.useRef({}).current;
21
+ const dataRef = React.useRef(defaultObj(perms));
22
+ const defaultActions = React.useRef(extendObj(true,{},mDefaultAction,defaultActions)).current;
227
23
  const data = dataRef.current;
228
- const onChange = (arg)=>{
229
- if(isMasterAdmin) return;
24
+ disabled = !!disabled || isUserMasterAdmin;
25
+ tablePermPrefix = defaultStr(tablePermPrefix,"table/").toLowerCase();
26
+ const onChange = disabled ? undefined : (arg)=>{
230
27
  let {data,resource} = arg;
231
28
  if(!isNonNullString(resource)) return;
232
29
  const sData = dataRef.current;
233
30
  data = defaultObj(data);
234
31
  for(let i in allPerms){
235
- if(i.toLowerCase().startsWith(resource)){
32
+ if(hasResource(i,resource)){
236
33
  if(isUndefined(data[i])){
237
34
  delete sData[i];
238
35
  } else {
@@ -241,158 +38,108 @@ const PermLines = React.forwardRef((props,ref)=>{
241
38
  }
242
39
  }
243
40
  dataRef.current = sData;
244
- if(props.onChange){
245
- props.onChange({...arg,data:sData});
41
+ if(cOnChange){
42
+ cOnChange({...arg,data:sData});
246
43
  }
247
44
  }
248
-
249
45
  testID = defaultStr(testID,"RN_PermsLines");
250
- const eProps = {style:[theme.styles.w100],containerProps:{style:[theme.styles.w100]}};
251
46
  const context = React.useRef({}).current;
252
47
  context.getData = x=> data;
253
48
  React.setRef(ref,context);
254
49
  React.useEffect(()=>{
255
50
  return ()=>{
256
- allPerms = {};
257
51
  React.setRef(ref,null);
258
52
  }
259
53
  },[]);
260
54
 
261
- return <Grid testID={testID}>
262
- <Cell tabletSize={10} desktopSize={6} phoneSize={12}>
263
- <Expandable expandIconProps = {expandIconProps} titleProps = {{style:styles.expandable}} title={"Table des données"} {...eProps}>
264
- <React.Fragment>
265
- {
266
- Object.mapToArray(tables,(table,tableName)=>{
267
- if(!isObj(table) || !isObj(table.perms)) return null;
268
- tableName = tableName.toLowerCase().trim();
269
- let text = defaultStr(table.text,table.label)
270
- let key = ("table/"+tableName);
271
- const perms = {};
272
- Object.map(table.perms,(perm,i)=>{
273
- const iLower = i.toLowerCase();
274
- if(iLower == 'defaultactions' || iLower =='defaultaction'){
275
- perms.defaultActions = perm;
276
- }
277
- if(!isObj(perm)) return ;
278
- if(perm.defaultActions){
279
- perm.actions = {
280
- ...defaultActions,
281
- ...defaultObj(perm.actions)
282
- }
283
- }
284
- i = i.toLowerCase();
285
- let k = key.toLowerCase();
286
- i = (k+"/"+i.ltrim(k)).rtrim("/").replaceAll("//","/");
287
- perms[i] = perm;
288
- });
289
- return <PermLine
290
- isMasterAdmin = {isMasterAdmin}
291
- table = {tableName}
292
- type = {"table"}
293
- perms = {perms}
294
- data = {data}
295
- onChange = {onChange}
296
- text = {text}
297
- resource = {key}
298
- key = {key}
299
- index = {key}
300
- user = {user}
301
- />
302
- })
303
- }
304
- </React.Fragment>
305
- <React.Fragment>
306
- {
307
- Object.mapToArray(PERMS,(table,tableName)=>{
308
- if(!isObj(table) || !isObj(table.perms)) return null;
309
- tableName = tableName.toLowerCase().trim();
310
- let text = defaultStr(table.text,table.label)
311
- let key = ("table/"+tableName);
312
- let perms = {};
313
- perms[key] = {actions:{},text}
314
- Object.map(table.perms,(perm,i)=>{
315
- if(!isObj(perm)) return ;
316
- if(perms.defaultActions){
317
- perms[key].actions = {
318
- ...defaultActions,
319
- ...perms[key].actions
320
- }
321
- } else {
322
- perms[key].actions[i] = perm;
323
- }
324
- })
325
- return <PermLine
326
- isMasterAdmin = {isMasterAdmin}
327
- table = {tableName}
328
- type = {"extra"}
329
- perms = {perms}
330
- data = {data}
331
- onChange = {onChange}
332
- text = {text}
333
- resource = {key}
334
- key = {key}
335
- index = {key}
336
- user = {user}
337
- />
338
- })
55
+ const content = React.useMemo(()=>{
56
+ const content = [];
57
+ Object.map(tables,(table,tableName)=>{
58
+ if(!isObj(table) || !isObj(table.perms)) return null;
59
+ tableName = defaultStr(table.tableName,table.table,tableName).toLowerCase().trim();
60
+ const text = defaultStr(table.text,table.label)
61
+ const resource = (tablePermPrefix+tableName.ltrim(tablePermPrefix)).toLowerCase();
62
+ const perms = {};
63
+ Object.map(table.perms,(perm,i)=>{
64
+ if(perm ===false) {
65
+ perms[i] = false;
66
+ return;
67
+ }
68
+ if(!isObj(perm)) return;
69
+ const iLower = i.toLowerCase();
70
+ if(iLower == 'defaultactions' || iLower =='defaultaction'){
71
+ perms.defaultActions = perm;
339
72
  }
340
- </React.Fragment>
341
- </Expandable>
342
- </Cell>
343
- <Cell tabletSize={8} desktopSize={6} phoneSize={12} >
344
- <Expandable expandIconProps = {expandIconProps} titleProps = {{style:styles.expandable}} title="Données de structure" {...eProps}>
345
- {
346
- Object.mapToArray(structData,(table,tableName)=>{
347
- if(!isObj(table)) return null;
348
- tableName = tableName.toLowerCase().trim();
349
- let text = defaultStr(table.text,table.label)
350
- let key = "structdata/"+tableName
351
- let perms = {};
352
- Object.map(table.perms,(perm,i)=>{
353
- /**** l'on peut décider d'ajouter les actions par défaut à une permission
354
- * dans ce cas, il suffit dans la table des permissions, de préciser la valeur défault action
355
- */
356
- if(arrayValueExists(['defaultactions','defaultaction'],i.toLowerCase())){
357
- perms.defaultActions = perm;
358
- }
359
- if(!isObj(perm)) return ;
360
- if(perm.defaultActions){
361
- perm.actions = {
362
- ...defaultActions,
363
- ...defaultObj(perm.actions)
364
- }
365
- }
366
- i = i.toLowerCase();
367
- let k = key.toLowerCase();
368
- i = (k+"/"+i.ltrim(k)).rtrim("/").replaceAll("//","/");
369
- perms[i] = perm;
370
- })
371
- return <PermLine
372
- isMasterAdmin = {isMasterAdmin}
373
- table = {tableName}
374
- type = {"structdata"}
375
- perms = {perms}
376
- data = {data}
377
- onChange = {onChange}
378
- text = {text}
379
- resource = {key}
380
- key = {key}
381
- index = {key}
382
- user = {user}
383
- />
384
- })
73
+ if(perm.defaultActions){
74
+ perm.actions = {
75
+ ...Object.clone(defaultActions),
76
+ ...defaultObj(perm.actions)
77
+ }
385
78
  }
386
- </Expandable>
387
- </Cell>
388
- </Grid>
79
+ i = i.toLowerCase();
80
+ i = (resource+"/"+i.ltrim(resource)).ltrim("/").replaceAll("//","/").rtrim("/").ltrim("/");
81
+ perms[i] = perm;
82
+ });
83
+ content.push(<PermLine
84
+ cellProps={cellProps}
85
+ {...permLineProps}
86
+ allPerms = {allPerms}
87
+ isUserMasterAdmin = {isUserMasterAdmin}
88
+ disabled = {disabled}
89
+ table = {tableName}
90
+ tablePermPrefix = {tablePermPrefix}
91
+ perms = {perms}
92
+ data = {data}
93
+ defaultActions = {defaultActions}
94
+ onChange = {onChange}
95
+ text = {text}
96
+ resource = {resource}
97
+ key = {resource}
98
+ index = {resource}
99
+ user = {user}
100
+ />);
101
+ })
102
+ return content;
103
+ },[tables,allPerms,isUserMasterAdmin,disabled,tablePermPrefix])
104
+ return <Expandable {...props} testID={testID} style={[theme.styles.w100,style]} containerProps={containerProps} titleProps = {{style:[styles.expandable,theme.styles.w100]}} title={title}>
105
+ <Grid testID={testID+"_Grid"} {...gridProps}>
106
+ {content }
107
+ </Grid>
108
+ </Expandable>
389
109
  });
390
110
 
391
- PermLines.displayName = "PermsLines";
111
+ PermLines.displayName = "AuthPermsLinesComponent";
112
+ const PermTextType = PropTypes.shape({
113
+ text : PropTypes.string,//le texte de la permission
114
+ label : PropTypes.string,
115
+ title : PropTypes.string, //le tooltip associé à la permission
116
+ tooltip : PropTypes.string, //alias à title,
117
+ actions : PropTypes.objectOf(PermTextType),//les actions supportées par la permission
118
+ defaultAction : PropTypes.bool,//si les actions par défaut seront associés à la permission en cours
119
+ });
392
120
 
393
121
  PermLines.propTypes = {
394
122
  data : PropTypes.object,
395
- perms : PropTypes.object
123
+ gridProps : PropTypes.object,//les props du composant Grid, wrapper au contentu expandable
124
+ isUserMasterAdmin : PropTypes.bool,//si l'utilisateur pour lequel on modifie la permission est un master admin
125
+ ///les tables associées aux permissions
126
+ tables : PropTypes.objectOf(
127
+ PropTypes.shape({
128
+ table : PropTypes.string,
129
+ tableName : PropTypes.string,
130
+ perms : PropTypes.object,
131
+ })
132
+ ).isRequired,
133
+ perms : PropTypes.object,
134
+ /*** si les élements de permissions seront modifiable où non */
135
+ disabled : PropTypes.bool,
136
+ tablePermPrefix : PropTypes.string,/*** le prefixe de permission à jouter à chaque permissions de table de donénes, exemple : 'table/', pour le prefix des permissions de type table de données */
137
+ title : PropTypes.oneOfType([
138
+ PropTypes.node,
139
+ PropTypes.element,
140
+ PropTypes.string,
141
+ ]), //le titre des permission liés à la table de données
142
+ defaultActions : PropTypes.object,//les actions par défaut aux permissions
396
143
  }
397
144
 
398
145
  export default PermLines;
@@ -0,0 +1,62 @@
1
+ import React from "$react";
2
+ import Checkbox from "$ecomponents/Checkbox";
3
+ import PropTypes from "prop-types";
4
+ import {defaultStr,defaultVal,defaultObj} from "$cutils";
5
+ import { StyleSheet } from "react-native";
6
+ import theme from "$theme";
7
+
8
+ const PermText = React.forwardRef(({isUserMasterAdmin,disabled,assignPerm,testID,text,title,label,checked,labelStyle,table,type,onToggle,actions,action,resource,tooltip,...props},ref)=>{
9
+ testID = defaultStr(testID,"RN_AuthPermTextComponent");
10
+ return <Checkbox
11
+ title = {tooltip || title}
12
+ ref = {ref}
13
+ testID = {testID}
14
+ disabled = {disabled || isUserMasterAdmin}
15
+ defaultValue = {checked || isUserMasterAdmin?1 : 0}
16
+ style = {[theme.styles.noPadding,theme.styles.noMarging,labelStyle !== false && styles.checkbox]}
17
+ labelStyle = {[labelStyle !== false && styles.label,labelStyle && labelStyle]}
18
+ label = {defaultVal(label,text)}
19
+ onPress = {(args)=>{
20
+ React.stopEventPropagation(args?.event);
21
+ if(onToggle){
22
+ onToggle({...args,...props,checked:!!!checked,resource,actions,action,table,type})
23
+ }
24
+ return false;
25
+ }}
26
+ />
27
+ })
28
+
29
+ PermText.displayName = "AuthPermTextComponent";
30
+ export default PermText;
31
+
32
+ PermText.propTypes = {
33
+ ...defaultObj(Checkbox.propTypes),
34
+ table : PropTypes.string,
35
+ type : PropTypes.string,//le type de données pour la table passée en paramètre
36
+ action : PropTypes.string,
37
+ //actions : PropTypes.arrayOf(PropTypes.string),
38
+ resource : PropTypes.string,
39
+ labelStyle : PropTypes.oneOfType([
40
+ PropTypes.bool,
41
+ theme.StyleProp,
42
+ ]),
43
+ }
44
+
45
+ const styles = StyleSheet.create({
46
+ expandableContent : {
47
+ paddingLeft : 30,
48
+ },
49
+ expandable : {
50
+ paddingLeft : 10,
51
+ },
52
+ label : {fontSize:14},
53
+ permChildren : {
54
+ paddingLeft : 20,
55
+ },
56
+ checkbox : {
57
+ //width : 20,
58
+ //height : 20,
59
+ margin : 0,
60
+ padding: 0,
61
+ }
62
+ });
@@ -11,5 +11,7 @@ export default [AuthSignInScreen,UserProfileScreen,
11
11
 
12
12
  //export {PermProfiles};
13
13
 
14
- //export {default as PermLines} from "./PermLines";
14
+ export {default as PermLines} from "./PermLines";
15
+ export {default as PermLine} from "./PermLine";
16
+ export {default as PermText} from "./PermText";
15
17
  //export {default as PermProfile} from "./PermProfile";
@@ -1,7 +1,42 @@
1
1
  import APP from "$capp/instance";
2
2
  import i18n from "$i18n";
3
+ import {isNonNullString} from "$cutils";
3
4
 
4
5
  export const getTitle = x => APP.name+" "+APP.version+"/"+i18n.lang("login");
5
6
  export const title = getTitle();
6
7
 
7
- export const screenName = "UserProfile";
8
+ export const screenName = "UserProfile";
9
+
10
+ export const hasResource = (permAction,resource)=>{
11
+ if(!isNonNullString(permAction) || !isNonNullString(resource)) return false;
12
+ permAction = permAction.toLowerCase().trim();
13
+ resource = resource.toLowerCase().trim();
14
+ return permAction == resource || permAction.startsWith(resource.rtrim("/")+"/");
15
+ }
16
+
17
+ export const defaultActions = {
18
+ create : {
19
+ text : 'Créer',
20
+ },
21
+ update : {
22
+ text : 'Modifier',
23
+ alias : 'edit',
24
+ },
25
+ delete : {
26
+ text : 'Supprimer',
27
+ alias : 'remove'
28
+ },
29
+ read : {
30
+ text : 'Consulter',
31
+ },
32
+ exporttoexcel : {
33
+ text : "Exporter au format Excel",
34
+ tooltip : "Peut exporter au format excel",
35
+ alias : 'exportexcel'
36
+ },
37
+ exporttopdf : {
38
+ text : "Exporter au format pdf",
39
+ tooltip : "Peut exporter au format pdf",
40
+ alias : 'exportpdf'
41
+ },
42
+ }