@fto-consult/expo-ui 2.48.2 → 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.
@@ -5,6 +5,7 @@ import {isMobileOrTabletMedia} from "$cplatform/dimensions";
5
5
  import {MAX_WIDTH} from "$ecomponents/Dialog/utils";
6
6
  import {extendObj,defaultObj,isObj,defaultBool,defaultStr} from "$utils";
7
7
  import grid from "$theme/grid";
8
+ import {isDesktopMedia} from "$cdimensions";
8
9
 
9
10
  let dialogProviderRef = null;
10
11
 
@@ -59,7 +60,8 @@ const FormDataDialogProvider = React.forwardRef((props,innerRef)=>{
59
60
  const isMob = isMobileOrTabletMedia();
60
61
  if(closeAction === true || state.closeAction === true) return rest;
61
62
  rest.windowWidth = !isMob ? MAX_WIDTH : undefined;
62
- rest.actions = Array.isArray(rest.actions)? [...rest.actions] : isObj(rest.actions)? {...rest.actions} : null;
63
+ rest.actions = Array.isArray(rest.actions)? Object.clone(rest.actions) : isObj(rest.actions)? Object.clone(rest.actions) : null;
64
+ rest.cancelButton = false;
63
65
  if(rest.actions && (!isMob || rest.fullScreen === false)){
64
66
  if(isDesktopMedia() && typeof rest.maxActions !=='number'){
65
67
  rest.maxActions = 2;
@@ -67,7 +69,7 @@ const FormDataDialogProvider = React.forwardRef((props,innerRef)=>{
67
69
  const closeBtn ={
68
70
  text : 'Annuler',
69
71
  icon : 'close',
70
- secondary : true,
72
+ isCancelButton : true,
71
73
  ...defaultObj(closeAction),
72
74
  onPress : context.close,
73
75
  isAction : false,
@@ -59,6 +59,7 @@ export default class FormDataActionComponent extends FormData {
59
59
  const cb = ()=>{
60
60
  if(typeof mainProps.onBackActionPress =='function' && mainProps.onBackActionPress(args) === false) return
61
61
  else if(hasP && typeof this.props.onBackActionPress =='function' && this.props.onBackActionPress(args) === false) return;
62
+ else if(typeof this.props.onCancel =='function' && this.props.onCancel(args) === false) return;
62
63
  if(typeof callback =='function'){
63
64
  return callback(args);
64
65
  }
@@ -48,7 +48,7 @@ export const getAppBarActionsProps = function(_props){
48
48
  action.tooltip +=" ("+keyboardShortcuts[shortcut]+")";
49
49
  }
50
50
  }
51
- isAction = defaultBool(isAction,canSave,true);
51
+ isAction = defaultBool(isAction,canSave,rest.isAction,rest.canSave,true);
52
52
  action.formName = formName;
53
53
  if(isAction) {
54
54
  action.isFormAction = true;
@@ -91,7 +91,6 @@ export const handleBeforeSaveCallback = (beforeSaveCallback,successCb,arg)=>{
91
91
  }
92
92
  successCb(arg);
93
93
  }).catch((e)=>{
94
- console.log(e,' form-list-saving-data')
95
94
  if(isNonNullString(e)){
96
95
  notify.error(e);
97
96
  } else if(e){
@@ -15,4 +15,6 @@ export const ICON_OFFSET = 12;
15
15
 
16
16
  export const CHECKED_ICON = isIos()? 'check' : "checkbox-marked";
17
17
 
18
+ export const CHECK_ICON = 'check';
19
+
18
20
  export const UNCHECKED_ICON = "checkbox-blank-outline";
@@ -5,10 +5,13 @@ import View from "$ecomponents/View";
5
5
  import theme from "$theme";
6
6
  import {defaultStr,defaultObj} from "$utils";
7
7
  import APP from "$capp/instance";
8
- const ScrollViewComponent = React.forwardRef(({virtualized,contentProps,containerProps,mediaQueryUpdateNativeProps,testID:customTestID,children:cChildren,screenIndent:sIndent,...rest},ref) => {
9
- const isKeyboardOpenRef = React.useRef(false);
8
+ const ScrollViewComponent = React.forwardRef(({virtualized,vertical,horizontal,contentProps,containerProps,mediaQueryUpdateNativeProps,testID:customTestID,children:cChildren,screenIndent:sIndent,...rest},ref) => {
10
9
  const testID = defaultStr(customTestID,'RN_ScrollViewComponent');
11
10
  containerProps = defaultObj(containerProps)
11
+ if(horizontal === true || vertical === false){
12
+ return <ScrollView horizontal testID={testID} ref={ref} {...rest} children={cChildren}/>
13
+ }
14
+ const isKeyboardOpenRef = React.useRef(false);
12
15
  const layoutRef = React.useRef(null);
13
16
  const [layout,setLayout] = React.useState(Dimensions.get("window"));
14
17
  const {height} = layout;
@@ -60,6 +63,7 @@ const ScrollViewComponent = React.forwardRef(({virtualized,contentProps,containe
60
63
  }} {...containerProps} style={[theme.styles.w100,containerProps.style]} testID={testID+"_ScrollViewContainer"}>
61
64
  <ScrollView
62
65
  ref={ref} {...rest}
66
+ vertical = {vertical}
63
67
  testID={testID}
64
68
  children={children}
65
69
  contentContainerStyle = {contentContainerStyle}
@@ -71,6 +75,9 @@ ScrollViewComponent.displayName = "ScrollViewComponent";
71
75
  export default ScrollViewComponent;
72
76
 
73
77
  ScrollViewComponent.propTypes = {
78
+ ...defaultObj(ScrollView.propTypes),
79
+ horizontal : PropTypes.bool,
80
+ vertical : PropTypes.bool,
74
81
  virtualized : PropTypes.bool,
75
82
  contentProps : PropTypes.object,
76
83
  }
@@ -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
+ });