@fto-consult/expo-ui 2.48.0 → 2.48.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/auth/Login.js +5 -1
- package/src/components/AppBar/index.js +1 -1
- package/src/components/AppBar/utils.js +2 -2
- package/src/components/BottomSheet/Menu.js +1 -1
- package/src/components/Button/index.js +11 -5
- package/src/components/Checkbox/index.js +1 -1
- package/src/components/Color/index.js +1 -1
- package/src/components/Countries/resources/countries-normalized.json +1987 -1987
- package/src/components/Countries/resources/countries-with-not-extra.json +1211 -1211
- package/src/components/Countries/resources/countries.sql +243 -243
- package/src/components/Datagrid/Accordion/Row.js +1 -1
- package/src/components/Datagrid/Actions/index.js +1 -1
- package/src/components/Datagrid/Footer/index.js +1 -1
- package/src/components/Date/DatePickerInput/index.js +1 -1
- package/src/components/Date/Time.js +1 -1
- package/src/components/Dialog/Dialog.js +9 -5
- package/src/components/Drawer/DrawerItems/ExpandableItem.js +1 -1
- package/src/components/Drawer/index.js +1 -1
- package/src/components/Dropdown/index.js +4 -1
- package/src/components/Fab/Group.js +1 -1
- package/src/components/Form/Fields/Checkbox.js +0 -5
- package/src/components/Form/Fields/Field.js +2 -1
- package/src/components/Form/Fields/Radio.js +0 -5
- package/src/components/Form/Fields/SelectField.js +1 -0
- package/src/components/Form/Fields/Slider.js +0 -5
- package/src/components/Form/Fields/Switch.js +0 -5
- package/src/components/Form/FormData/DialogProvider.js +4 -2
- package/src/components/Form/FormData/FormDataActions.js +1 -0
- package/src/components/Form/FormData/componentsTypes.js +2 -2
- package/src/components/Form/FormData/utils.js +1 -2
- package/src/components/Icon/Checkbox.js +2 -2
- package/src/components/Icon/utils.js +2 -0
- package/src/components/Image/Editor/index copy.js +1 -1
- package/src/components/Image/Editor/index.js +2 -2
- package/src/components/Label/index.js +1 -1
- package/src/components/Menu/index.js +1 -1
- package/src/components/Modal/index.js +1 -1
- package/src/components/PhoneInput/index.js +1 -1
- package/src/components/Radio/index.js +1 -1
- package/src/components/ScrollView/index.js +9 -2
- package/src/components/SimpleSelect/index.js +1 -1
- package/src/components/Slider/index.js +1 -1
- package/src/components/Switch/index.js +1 -1
- package/src/components/Table/FiltersOrFooters.js +18 -0
- package/src/components/Table/index.js +32 -14
- package/src/components/TextField/index.js +3 -3
- package/src/screens/Auth/PermLines.js +417 -0
- package/src/screens/Auth/PermProfile.js +182 -0
- package/src/screens/Auth/PermProfiles.js +38 -0
- package/src/screens/Auth/Profile.js +1 -1
- package/src/screens/Auth/index.js +8 -1
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
import tables from "$database/data/tables";
|
|
2
|
+
import Checkbox from "$components/Checkbox";
|
|
3
|
+
import React from "$react";
|
|
4
|
+
import { StyleSheet } from "react-native";
|
|
5
|
+
import {defaultVal,defaultObj,defaultBool,arrayValueExists} from "$utils";
|
|
6
|
+
import Auth from "$cauth";
|
|
7
|
+
import Label from "$ecomponents/Label";
|
|
8
|
+
import View from "$ecomponents/View";
|
|
9
|
+
import Expandable from "$ecomponents/Expandable";
|
|
10
|
+
import PropTypes from "prop-types";
|
|
11
|
+
import Grid,{Cell} from "$components/Grid";
|
|
12
|
+
import theme from "$theme";
|
|
13
|
+
import appConfig from "$capp/config";
|
|
14
|
+
|
|
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;
|
|
227
|
+
const data = dataRef.current;
|
|
228
|
+
const onChange = (arg)=>{
|
|
229
|
+
if(isMasterAdmin) return;
|
|
230
|
+
let {data,resource} = arg;
|
|
231
|
+
if(!isNonNullString(resource)) return;
|
|
232
|
+
const sData = dataRef.current;
|
|
233
|
+
data = defaultObj(data);
|
|
234
|
+
for(let i in allPerms){
|
|
235
|
+
if(i.toLowerCase().startsWith(resource)){
|
|
236
|
+
if(isUndefined(data[i])){
|
|
237
|
+
delete sData[i];
|
|
238
|
+
} else {
|
|
239
|
+
sData[i] = data[i]
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
dataRef.current = sData;
|
|
244
|
+
if(props.onChange){
|
|
245
|
+
props.onChange({...arg,data:sData});
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
testID = defaultStr(testID,"RN_PermsLines");
|
|
250
|
+
const eProps = {style:[theme.styles.w100],containerProps:{style:[theme.styles.w100]}};
|
|
251
|
+
const context = React.useRef({}).current;
|
|
252
|
+
context.getData = x=> data;
|
|
253
|
+
React.setRef(ref,context);
|
|
254
|
+
React.useEffect(()=>{
|
|
255
|
+
return ()=>{
|
|
256
|
+
allPerms = {};
|
|
257
|
+
React.setRef(ref,null);
|
|
258
|
+
}
|
|
259
|
+
},[]);
|
|
260
|
+
|
|
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
|
+
})
|
|
339
|
+
}
|
|
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
|
+
})
|
|
385
|
+
}
|
|
386
|
+
</Expandable>
|
|
387
|
+
</Cell>
|
|
388
|
+
</Grid>
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
PermLines.displayName = "PermsLines";
|
|
392
|
+
|
|
393
|
+
PermLines.propTypes = {
|
|
394
|
+
data : PropTypes.object,
|
|
395
|
+
perms : PropTypes.object
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
export default PermLines;
|
|
399
|
+
|
|
400
|
+
const styles = StyleSheet.create({
|
|
401
|
+
expandableContent : {
|
|
402
|
+
paddingLeft : 30,
|
|
403
|
+
},
|
|
404
|
+
expandable : {
|
|
405
|
+
paddingLeft : 10,
|
|
406
|
+
},
|
|
407
|
+
label : {fontSize:14},
|
|
408
|
+
permChildren : {
|
|
409
|
+
paddingLeft : 20,
|
|
410
|
+
},
|
|
411
|
+
checkbox : {
|
|
412
|
+
//width : 20,
|
|
413
|
+
//height : 20,
|
|
414
|
+
margin : 0,
|
|
415
|
+
padding: 0,
|
|
416
|
+
}
|
|
417
|
+
});
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import showConfirm from "$components/Dialog/confirm";
|
|
2
|
+
import notify from "$components/Dialog/notify";
|
|
3
|
+
import {defaultArray,arrayValueExists,defaultStr,uniqid} from "$utils";
|
|
4
|
+
import userDbName from "$database/data/tables/users/dbName";
|
|
5
|
+
import Auth from "$auth";
|
|
6
|
+
import getData from "$database/getData";
|
|
7
|
+
import getDB from "$database/getDB";
|
|
8
|
+
import {FormData,getForm,getFormData} from "$components/Form";
|
|
9
|
+
import Icon from "$components/Icon";
|
|
10
|
+
import React from "$react";
|
|
11
|
+
import Label from "$components/Label";
|
|
12
|
+
import {open as showPreloader,close as hidePreloader} from "$preloader";
|
|
13
|
+
import Expandable from "$components/Expandable";
|
|
14
|
+
import theme from "$theme";
|
|
15
|
+
import View from "$components/View";
|
|
16
|
+
import Link from "$components/Link";
|
|
17
|
+
import Button from "$components/Button";
|
|
18
|
+
|
|
19
|
+
const tableName = Auth.permProfilesTableName.toUpperCase();
|
|
20
|
+
|
|
21
|
+
const PermProfile = React.forwardRef((props,ref)=>{
|
|
22
|
+
const formName = React.useRef(defaultStr(props.formName,uniqid("perm-profile-name"))).current;
|
|
23
|
+
const user = defaultObj(props.user);
|
|
24
|
+
const permDataRef = React.useRef({});
|
|
25
|
+
const dialogProviderRef = React.useRef(null);
|
|
26
|
+
const {isMasterAdmin,text,label,editProfileRouteName} = props;
|
|
27
|
+
const [state,setState] = React.useState({
|
|
28
|
+
profiles : {},
|
|
29
|
+
selected : defaultArray(user.permProfiles),
|
|
30
|
+
loading : true,
|
|
31
|
+
canAssignPerms : Auth.isTableDataAllowed({table:'users',action:'assignPerms'}),
|
|
32
|
+
canViewPerms : Auth.isTableDataAllowed({table:'users',action:'readPerms'})
|
|
33
|
+
});
|
|
34
|
+
const {canAssignPerms,canViewPerms,selected} = state;
|
|
35
|
+
const reload = ()=>{
|
|
36
|
+
getData(userDbName+"["+tableName+"]").then((profiles)=>{
|
|
37
|
+
setState({...state,profiles,loading:false})
|
|
38
|
+
}).catch((e)=>{
|
|
39
|
+
setState({...state,loading:false})
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
const assignProfile = (profile,select)=>{
|
|
43
|
+
if(isMasterAdmin) return null;
|
|
44
|
+
const {selected} = state;
|
|
45
|
+
profile = defaultObj(profile);
|
|
46
|
+
const sel = [];
|
|
47
|
+
const allP = {};
|
|
48
|
+
if(selected.length <= 0){
|
|
49
|
+
if(select){
|
|
50
|
+
sel.push(profile.code);
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
for(let i in selected){
|
|
54
|
+
const val = selected[i];
|
|
55
|
+
if(selected[i] == profile.code){
|
|
56
|
+
if(select && !allP[profile.code]){
|
|
57
|
+
sel.push(profile.code);
|
|
58
|
+
allP[profile.code] = true;
|
|
59
|
+
}
|
|
60
|
+
} else if(!allP[val]) {
|
|
61
|
+
sel.push(val);
|
|
62
|
+
allP[val] = true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if(select && !allP[profile.code]){
|
|
66
|
+
sel.push(profile.code);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
setState({...state,selected:sel});
|
|
70
|
+
if(props.onChange){
|
|
71
|
+
props.onChange({context:{},...state,selected:sel});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const onChange = ({data})=>{
|
|
75
|
+
permDataRef.current = data;
|
|
76
|
+
}
|
|
77
|
+
const onSaveProfile = ({data,goBack})=>{
|
|
78
|
+
const d = {...data,table:tableName,perms:permDataRef.current};
|
|
79
|
+
if(!isNonNullString(d._id)) return;
|
|
80
|
+
showPreloader()
|
|
81
|
+
getDB(userDbName).then(({db})=>{
|
|
82
|
+
db.upsert(d._id,()=>{
|
|
83
|
+
return d;
|
|
84
|
+
}).then((up)=>{
|
|
85
|
+
let d = up.newDoc;
|
|
86
|
+
notify.success("Le profil ["+d.code+"] a été inséré/modifié avec succès");
|
|
87
|
+
reload();
|
|
88
|
+
if(goBack){
|
|
89
|
+
goBack(true);
|
|
90
|
+
}
|
|
91
|
+
hidePreloader();
|
|
92
|
+
}).catch((e)=>{
|
|
93
|
+
console.log(e," upserting profile group");
|
|
94
|
+
hidePreloader();
|
|
95
|
+
});
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
const removeProfile = (profile)=>{
|
|
99
|
+
if(!isObj(profile) || !isNonNullString(profile.code) || !isNonNullString(profile._id)){
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
showConfirm({
|
|
103
|
+
title:'Suppr profil['+profile.code+"]",
|
|
104
|
+
msg : 'Voulez vous vraiment supprimer le profil <<'+profile.code+">>",
|
|
105
|
+
onSuccess : ()=>{
|
|
106
|
+
getDB(userDbName).then(({db})=>{
|
|
107
|
+
showPreloader('Suppression du profil '+defaultStr(profile.code)+"...");
|
|
108
|
+
db.get(profile._id).then((doc)=>{
|
|
109
|
+
db.remove(doc).then((e)=>{
|
|
110
|
+
hidePreloader();
|
|
111
|
+
notify.success("Le profil ["+profile.code+"] a été supprimé avec succès");
|
|
112
|
+
reload();
|
|
113
|
+
});
|
|
114
|
+
}).catch((e)=>{
|
|
115
|
+
console.log(e,' is removing doc profile')
|
|
116
|
+
hidePreloader();
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
React.useEffect(()=>{
|
|
123
|
+
if(!canAssignPerms && !canViewPerms) return;
|
|
124
|
+
reload();
|
|
125
|
+
return ()=>{
|
|
126
|
+
|
|
127
|
+
}
|
|
128
|
+
},[])
|
|
129
|
+
if(!canAssignPerms && !canViewPerms) return null;
|
|
130
|
+
const profiles = [];
|
|
131
|
+
Object.map(state.profiles,(profile,index)=>{
|
|
132
|
+
if(!isObj(profile) || !isNonNullString(profile.code)){
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
const isAssigned = isMasterAdmin? true : arrayValueExists(selected,profile.code);
|
|
136
|
+
profiles.push(<View key={index} style={[theme.styles.row,{justifyContent:'space-between'}]}>
|
|
137
|
+
<Label>{profile.code}</Label>
|
|
138
|
+
<View style={[theme.styles.row]}>
|
|
139
|
+
<Icon primary title={isAssigned?'Profil de permission ['+profile.code+'] assigné à l\'utilisateur':'Profil de permission ['+profile.code+'] non assigné à l\'utilisateur '+defaultStr(user.code)} name={isAssigned?'checkbox-marked':'checkbox-blank-outline'}
|
|
140
|
+
onPress={()=>{
|
|
141
|
+
assignProfile(profile,isAssigned?false:true)
|
|
142
|
+
}}
|
|
143
|
+
/>
|
|
144
|
+
{canAssignPerms ? <Link Component = {Icon}
|
|
145
|
+
title={"Modifier le profil ["+profile.code+"]"}
|
|
146
|
+
name={"file-document-edit"}
|
|
147
|
+
success
|
|
148
|
+
routeParams = {{data:profile,formName,onChange,onSave:onSaveProfile}}
|
|
149
|
+
routeName = {editProfileRouteName}
|
|
150
|
+
/>:null}
|
|
151
|
+
{canAssignPerms ? <Icon
|
|
152
|
+
title={"Supprimer le profil ["+profile.code+"]"}
|
|
153
|
+
name={"delete"}
|
|
154
|
+
error
|
|
155
|
+
onPress={(e)=>{
|
|
156
|
+
React.stopEventPropagation(e);
|
|
157
|
+
removeProfile(profile);
|
|
158
|
+
}}
|
|
159
|
+
/> : null}
|
|
160
|
+
</View>
|
|
161
|
+
</View>)
|
|
162
|
+
})
|
|
163
|
+
return <Expandable title={defaultStr(label,text)+" ("+profiles.length.formatNumber()+")"} style={[theme.styles.p1]}>
|
|
164
|
+
<Link
|
|
165
|
+
primary
|
|
166
|
+
Component = {Button}
|
|
167
|
+
routeName = {editProfileRouteName}
|
|
168
|
+
routeParams = {{formName,onChange,onSave:onSaveProfile}}
|
|
169
|
+
icon={"text-box-plus-outline"}
|
|
170
|
+
mode = "contained"
|
|
171
|
+
>
|
|
172
|
+
Ajouter un profil
|
|
173
|
+
</Link>
|
|
174
|
+
<View style={[theme.styles.w100]}>
|
|
175
|
+
{profiles}
|
|
176
|
+
</View>
|
|
177
|
+
</Expandable>
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
PermProfile.tableName = PermProfile.table = tableName;
|
|
181
|
+
PermProfile.dbName = userDbName;
|
|
182
|
+
export default PermProfile;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import FormDataScreen from "$elayouts/Screen/FormData";
|
|
2
|
+
import {defaultStr,defaultObj} from "$utils";
|
|
3
|
+
import PermLines from "./PermLines";
|
|
4
|
+
import PropTypes from "prop-types";
|
|
5
|
+
import Label from "$components/Label";
|
|
6
|
+
import theme from "$theme";
|
|
7
|
+
|
|
8
|
+
export const screenName = "PermProfileScreens";
|
|
9
|
+
|
|
10
|
+
export default function PermProfilesScreen({onChange,fields,data,profile,perms,user,...props}){
|
|
11
|
+
return <FormDataScreen
|
|
12
|
+
{...props}
|
|
13
|
+
modal
|
|
14
|
+
withScrollView
|
|
15
|
+
header = {<Label primary upperCase textBold style={[theme.styles.p1]}>Permissions liées au profil</Label>}
|
|
16
|
+
fields = {isObj(fields) && Object.size(fields,true) && fields || { code : {
|
|
17
|
+
text : 'Nom du profil',
|
|
18
|
+
type : 'id',
|
|
19
|
+
maxLength:30,
|
|
20
|
+
primaryKey : true,
|
|
21
|
+
}}}
|
|
22
|
+
data = {defaultObj(profile,profile)}
|
|
23
|
+
testID = {"RN_PermProfile_FormData"}
|
|
24
|
+
title = {defaultStr(props.title,"Groupe de profil")}
|
|
25
|
+
children = {<PermLines user={user} perms = {perms} isMasterAdmin={false}
|
|
26
|
+
onChange={onChange}/>}
|
|
27
|
+
/>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
PermProfilesScreen.screenName = screenName;
|
|
31
|
+
|
|
32
|
+
PermProfilesScreen.Modal = true;
|
|
33
|
+
|
|
34
|
+
PermProfilesScreen.propTypes = {
|
|
35
|
+
user : PropTypes.object,//l'objet user
|
|
36
|
+
perms : PropTypes.object,//les permissions associées à l'utilisateur user
|
|
37
|
+
profile : PropTypes.object,//les informations sur le profil en cour de modification
|
|
38
|
+
}
|
|
@@ -16,7 +16,7 @@ export default function UserProfileScreen(props){
|
|
|
16
16
|
const themeRef = React.useRef(defaultObj(user.theme));
|
|
17
17
|
const hasChangeRef = React.useRef(false);
|
|
18
18
|
const authProfileFields = typeof SignIn2SignOut.authProfileFields =='function'?SignIn2SignOut.authProfileFields(props) : SignIn2SignOut.authProfileFields;
|
|
19
|
-
const fields = isObj(authProfileFields)? authProfileFields : {};
|
|
19
|
+
const fields = isObj(authProfileFields)? Object.clone(authProfileFields) : {};
|
|
20
20
|
const formFields = {
|
|
21
21
|
avatar : {
|
|
22
22
|
...avatarProps,
|
|
@@ -4,5 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
import AuthSignInScreen from "./SignIn";
|
|
6
6
|
import UserProfileScreen from "./Profile";
|
|
7
|
+
//import PermProfiles from "./PermProfiles";
|
|
8
|
+
export default [AuthSignInScreen,UserProfileScreen,
|
|
9
|
+
//PermProfiles
|
|
10
|
+
];
|
|
7
11
|
|
|
8
|
-
export
|
|
12
|
+
//export {PermProfiles};
|
|
13
|
+
|
|
14
|
+
//export {default as PermLines} from "./PermLines";
|
|
15
|
+
//export {default as PermProfile} from "./PermProfile";
|