@fto-consult/expo-ui 5.7.10 → 5.7.12

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": "5.7.10",
3
+ "version": "5.7.12",
4
4
  "description": "Bibliothèque de composants UI Expo,react-native",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/App.js CHANGED
@@ -5,23 +5,13 @@ import {defaultObj} from "$cutils";
5
5
  import {updateTheme,defaultTheme} from "$theme";
6
6
  import {Provider as PaperProvider } from 'react-native-paper';
7
7
  import Index from './index';
8
- import {Portal } from 'react-native-paper';
9
- import {PreloaderProvider} from "$epreloader";
10
- import DropdownAlert from '$ecomponents/Dialog/DropdownAlert';
11
- import notify, {notificationRef} from "$notify";
12
- import BottomSheetProvider from "$ecomponents/BottomSheet/Provider";
13
- import DialogProvider from "$ecomponents/Dialog/Provider";
14
- import { DialogProvider as FormDataDialogProvider } from '$eform/FormData';
8
+ import notify from "$notify";
15
9
  import { SafeAreaProvider } from 'react-native-safe-area-context';
16
10
  import { PreferencesContext } from './Preferences';
17
11
  import {AuthProvider} from '$cauth';
18
- import {PortalProvider } from '$ecomponents/Portal';
19
12
  import ErrorBoundary from "$ecomponents/ErrorBoundary";
20
- import ErrorBoundaryProvider from "$ecomponents/ErrorBoundary/Provider";
21
13
  import {GestureHandlerRootView} from "react-native-gesture-handler";
22
14
  import StatusBar from "$ecomponents/StatusBar";
23
- import SimpleSelect from '$ecomponents/SimpleSelect';
24
- import {Provider as AlertProvider} from '$ecomponents/Dialog/confirm/Alert';
25
15
  import APP from "$app";
26
16
  import FontIcon from "$ecomponents/Icon/Font"
27
17
  import {isMobileNative} from "$cplatform";
@@ -178,23 +168,12 @@ export default function getIndex({onMount,onUnmount,swrConfig,onRender,preferenc
178
168
  >
179
169
  <SafeAreaProvider>
180
170
  <AuthProvider>
181
- <PortalProvider>
182
- <Portal.Host>
183
- <ErrorBoundary>
184
- <StatusBar/>
185
- <PreferencesContext.Provider value={preferences}>
186
- <DropdownAlert ref={notificationRef}/>
187
- <PreloaderProvider/>
188
- <DialogProvider responsive/>
189
- <AlertProvider SimpleSelect={SimpleSelect}/>
190
- <FormDataDialogProvider/>
191
- {<Index {...rest} theme={theme}/>}
192
- <ErrorBoundaryProvider/>
193
- <BottomSheetProvider/>
194
- </PreferencesContext.Provider>
195
- </ErrorBoundary>
196
- </Portal.Host>
197
- </PortalProvider>
171
+ <ErrorBoundary>
172
+ <StatusBar/>
173
+ <PreferencesContext.Provider value={preferences}>
174
+ {<Index {...rest} theme={theme}/>}
175
+ </PreferencesContext.Provider>
176
+ </ErrorBoundary>
198
177
  </AuthProvider>
199
178
  </SafeAreaProvider>
200
179
  </PaperProvider>
@@ -2459,6 +2459,7 @@ export default class CommonDatagridComponent extends AppComponent {
2459
2459
  render,
2460
2460
  readOnly,
2461
2461
  disabled,
2462
+ editable,
2462
2463
  visible,
2463
2464
  defaultValue,
2464
2465
  id,
@@ -2469,7 +2470,7 @@ export default class CommonDatagridComponent extends AppComponent {
2469
2470
  } = header;
2470
2471
  restCol = Object.clone(defaultObj(restCol));
2471
2472
  let colFilter = defaultVal(restCol.filter,true);
2472
- field = header.field = defaultStr(header.field,field,headerIndex);
2473
+ field = header.field = restCol.field = defaultStr(header.field,field,headerIndex);
2473
2474
  delete restCol.filter;
2474
2475
 
2475
2476
  const type = defaultStr(header.jsType,header.type,"text").toLowerCase();
@@ -2617,14 +2618,14 @@ export default class CommonDatagridComponent extends AppComponent {
2617
2618
  this.sectionListColumnsSize.current++;
2618
2619
  }
2619
2620
  const mItem = {
2620
- ...header,
2621
+ ...restCol,
2621
2622
  field,
2622
2623
  type,
2623
2624
  onPress : ()=>{
2624
2625
  this.toggleColumnInSectionList(field);
2625
2626
  return false;
2626
2627
  },
2627
- title : title,
2628
+ title,
2628
2629
  icon : isInSectionListHeader?CHECKED_ICON_NAME : null,
2629
2630
  };
2630
2631
  if(this.isSectionListColumnConfigurable(mItem)){
@@ -35,8 +35,10 @@ const DrawerComponent = React.forwardRef((props,ref)=>{
35
35
  permanentToggleIcon,minimizedToggleIcon,temporaryToggleIcon,withMinimizedIcon,
36
36
  isItemActive,onPageResize,navigationViewRef,
37
37
  children,
38
+ testID,
38
39
  drawerType} = props;
39
40
  sessionName = defaultStr(sessionName);
41
+ testID = defaultStr(testID,"RN_DrawerComponent")
40
42
  const sessionRef = React.useRef({});
41
43
  const session = React.useMemo(()=>{
42
44
  if(sessionName){
@@ -251,8 +253,9 @@ const DrawerComponent = React.forwardRef((props,ref)=>{
251
253
  }
252
254
  return false;
253
255
  },getState:getDrawerState,getDrawerRef}}>
254
- <View style={styles.container}>
256
+ <View style={styles.container} testID={`${testID}_Container`}>
255
257
  <DrawerLayout
258
+ testID = {`${testID}_DrawerLayout`}
256
259
  {...restP}
257
260
  permanent = {isPermanent}
258
261
  onDrawerSlide={onDrawerSlide}
@@ -339,7 +342,7 @@ const DrawerComponent = React.forwardRef((props,ref)=>{
339
342
  {paddingBottom:30},
340
343
  contentContainerStyle
341
344
  ]
342
- }>
345
+ }>
343
346
  {children}
344
347
  </DrawerLayout>
345
348
  </View>
@@ -991,7 +991,7 @@ class DropdownComponent extends AppComponent {
991
991
  {...restProps}
992
992
  testID = {testID+"_ModalComponent"}
993
993
  withScrollView = {false}
994
- visible={visible && canHandle ? true : false}
994
+ visible={visible}
995
995
  onDismiss={this.hide.bind(this)}
996
996
  contentStyle = {[{paddingVertical:0},restProps.contentStyle]}
997
997
  anchor={anchor}
@@ -21,6 +21,9 @@ import appConfig from "$appConfig";
21
21
  */
22
22
  const TableDataSelectField = React.forwardRef(({foreignKeyColumn,bindUpsert2RemoveEvents,onAdd,showAdd:customShowAdd,canShowAdd,foreignKeyTable,fetchItemsPath,foreignKeyLabel,foreignKeyLabelIndex,dropdownActions,fields,fetchItems:customFetchItem,convertFiltersToSQL,mutateFetchedItems,getForeignKeyTable,onFetchItems,isFilter,isUpdate,isDocEditing,items,onAddProps,fetchOptions,...props},ref)=>{
23
23
  props.data = defaultObj(props.data);
24
+ if(!foreignKeyColumn && isNonNullString(props.field)){
25
+ foreignKeyColumn = props.field;
26
+ }
24
27
  if(isNonNullString(foreignKeyColumn)){
25
28
  foreignKeyColumn = foreignKeyColumn.trim();
26
29
  }
@@ -34,7 +37,7 @@ const TableDataSelectField = React.forwardRef(({foreignKeyColumn,bindUpsert2Remo
34
37
  fetchItemsPath = defaultStr(fetchItemsPath).trim();
35
38
 
36
39
  if(!fetchItemsPath && (!isObj(fKeyTable) || !(defaultStr(fKeyTable.tableName,fKeyTable.table)))){
37
- console.error("type de données invalide pour la foreignKeyTable ",fKeyTable," composant SelectTableData",foreignKeyColumn,foreignKeyTable,props);
40
+ console.error("type de données invalide pour la foreignKeyTable ",foreignKeyTable," label : ",foreignKeyLabel,fKeyTable," composant SelectTableData",foreignKeyColumn,foreignKeyTable,props);
38
41
  return null;
39
42
  }
40
43
  fKeyTable = defaultObj(fKeyTable);
@@ -280,13 +283,12 @@ const TableDataSelectField = React.forwardRef(({foreignKeyColumn,bindUpsert2Remo
280
283
  }
281
284
  return rItem(p);
282
285
  }}
283
- hideOnAdd
284
286
  onAdd = {(args)=>{
285
287
  onAddProps = defaultObj(isFunction(onAddProps)? onAddProps.call(context,{context,foreignKeyTable,dbName,props}) : onAddProps);
286
288
  if(typeof onAdd =='function'){
287
289
  return onAdd({...args,...onAddProps});
288
290
  }
289
- return navigateToTableData({...onAddProps,foreignKeyTable,table:foreignKeyTable,foreignKeyColumn,tableName : foreignKeyTable,...args})
291
+ return navigateToTableData(foreignKeyTable,{routeParams:{...onAddProps,foreignKeyTable,table:foreignKeyTable,foreignKeyColumn,tableName : foreignKeyTable}});
290
292
  }}
291
293
  />
292
294
  });
@@ -8,10 +8,10 @@ import Form from "../Form";
8
8
  import theme,{flattenStyle} from "$theme";
9
9
  import PropTypes from "prop-types";
10
10
  import {renderActions} from "$ecomponents/Dialog/utils";
11
- //import {isDocUpdate} from "$database/utils";
12
11
  import {handleBeforeSaveCallback} from "./utils";
12
+ import isDbDocEditing,{checkPrimaryKey} from "../utils/isDocEditing";
13
13
  import getComponentFromType from "./componentsTypes";
14
- import { keyboardShortcuts } from "../utils";
14
+ import keyboardShortcuts from "../utils/keyboardShortcuts";
15
15
  import appConfig from "$capp/config";
16
16
 
17
17
  export default class FormDataComponent extends AppComponent{
@@ -84,11 +84,10 @@ export default class FormDataComponent extends AppComponent{
84
84
  return "Impossible d'enregister les données à cause l'erreur suivante : "+errorText;
85
85
  }
86
86
  }
87
- const isDocEditing = this.isDocEditing(args.data);
88
87
  const isUpdated = this.isDocEditing(args.data);
89
88
  const currentIndex = this.getCurrentIndex();
90
89
  const action = typeof this.clickedAction =='string' ? this.clickedAction.toLowerCase() : '';
91
- const savedArgs = {...args,isDocEditing,context:this,action,currentIndex,index:currentIndex,isUpdate:isUpdated,isUpdated,props:this.props,context:this};
90
+ const savedArgs = {...args,isUpdated,context:this,action,currentIndex,index:currentIndex,isUpdate:isUpdated,isUpdated,props:this.props,context:this};
92
91
  if(beforeSaveArgumentsMutator){
93
92
  savedArgs = beforeSaveArgumentsMutator(savedArgs);
94
93
  if(!isObj(savedArgs)){
@@ -149,7 +148,9 @@ export default class FormDataComponent extends AppComponent{
149
148
  } else if(typeof this.props.isDocUpdate =='function'){
150
149
  return this.props.isDocUpdate(data,{context:this}) ? true : false;
151
150
  }
152
- return false;
151
+ return isObj(this.formDataPrimaryKeyFields) && Object.size(this.formDataPrimaryKeyFields,true) ? isDbDocEditing(data,this.formDataPrimaryKeyFields,({index:field,data})=>{
152
+ return checkPrimaryKey(data,field);
153
+ }) : false;
153
154
  }
154
155
  canBindResizeEvents(){
155
156
  return false;
@@ -180,6 +181,7 @@ export default class FormDataComponent extends AppComponent{
180
181
  formProps = defaultObj(formProps);
181
182
  const fieldProps = defaultObj(formProps.fieldProps,this.props.fieldProps);
182
183
  formProps.style = flattenStyle(formProps.style);
184
+ this.formDataPrimaryKeyFields = {};
183
185
  const content = [];
184
186
  const fields = defaultObj(formProps.fields,this.props.fields);
185
187
  const data = isObj(formProps.data) ? formProps.data : typeof this.props.data =='object' && this.props.data ? this.props.data : {};
@@ -198,6 +200,9 @@ export default class FormDataComponent extends AppComponent{
198
200
  rest = Object.assign({},rest);
199
201
  delete rest.import;
200
202
  delete rest.export;
203
+ if(primaryKey === true && name && !field.filter){
204
+ this.formDataPrimaryKeyFields[name] = field;
205
+ }
201
206
  if(form === false || ignore || (isNonNullString(perm) && !Auth.isAllowedFromStr(perm))){
202
207
  return null;
203
208
  }
@@ -12,4 +12,6 @@ export {FormData};
12
12
 
13
13
  export default FormData;
14
14
 
15
- FormData.DialogProvider = Provider;
15
+ FormData.DialogProvider = Provider;
16
+
17
+ export * from "./utils";
@@ -2,7 +2,7 @@ import {isNonNullString,isObj,defaultObj,isPromise,isFunction,defaultStr,isObjOr
2
2
  import notify from "$notify";
3
3
  import { getFormData } from "../utils/FormsManager";
4
4
  import {isMobileBrowser,isMobileNative} from "$cplatform";
5
- import { keyboardShortcuts as KeyboardShorts } from "../utils";
5
+ import KeyboardShorts from "../utils/keyboardShortcuts";
6
6
 
7
7
  export const keyboardShortcuts = {};
8
8
  Object.map(KeyboardShorts,(st,i)=>{
@@ -100,4 +100,5 @@ export const handleBeforeSaveCallback = (beforeSaveCallback,successCb,arg)=>{
100
100
  }
101
101
  successCb(arg);
102
102
  return bF;
103
- }
103
+ }
104
+
@@ -5,4 +5,6 @@ export {Forms};
5
5
 
6
6
  export {default as keyboardEvents} from "./keyboardEvents";
7
7
 
8
- export {default as keyboardShortcuts} from "./keyboardShortcuts";
8
+ export {default as isDocEditing} from "./isDocEditing";
9
+
10
+ export * from "./isDocEditing";
@@ -0,0 +1,44 @@
1
+ import {isObj,defaultStr} from "$cutils";
2
+ export const checkPrimaryKey = (data,f)=>{
3
+ return !(!(f in data) || (data[f] == null) || (!data[f] && typeof data !=='number'));
4
+ }
5
+
6
+ /*** vérifie si le document passé en paramètre est éditable
7
+ * @param {object} data la données à vérifier
8
+ * @param {object| array} les champs sur lesquels se baser pour vérifier si la donénes est une mise à jour
9
+ * @param {func} checkPrimaryKey la foncition permettant de vérifier s'il s'agit d'une clé primaire pour la données courante
10
+ */
11
+ const isDocEditing = (data,fields,checkPrimaryKey)=>{
12
+ if(!isObj(data) || !isObjOrArray(fields)) return false;
13
+ let hasPrimaryFields = false;
14
+ let hasValidated = true;
15
+ for(let i in fields){
16
+ const field = fields[i];
17
+ if(typeof checkPrimaryKey =='function') {
18
+ hasPrimaryFields = true;
19
+ if(checkPrimaryKey({field,i,index:i,data}) === false){
20
+ return false;
21
+ }
22
+ continue;
23
+ }
24
+ if(!isObj(field)) continue;
25
+ hasPrimaryFields = true;
26
+ const f = defaultStr(field.field,i);
27
+ if(field.primaryKey === true){
28
+ if(!checkPrimaryKey(data,f)){
29
+ if(hasPrimaryFields){
30
+ return false;
31
+ }
32
+ hasValidated = false;
33
+ }
34
+ }
35
+ }
36
+ if(hasPrimaryFields){
37
+ return hasValidated;
38
+ }
39
+ return false;
40
+ }
41
+
42
+ export default isDocEditing;
43
+
44
+ export const isDocUpdate = isDocEditing;
@@ -7,6 +7,7 @@ import View from "$ecomponents/View";
7
7
  import {isNativeMobile} from "$cplatform";
8
8
  import {defaultDecimal} from "$cutils";
9
9
  import {LogoProgress} from "$ecomponents/Logo";
10
+ import {defaultStr} from "$cutils";
10
11
  import styles, {
11
12
  _solidBackground,
12
13
  _staticBackground,
@@ -72,9 +73,11 @@ class AnimatedSplash extends React.Component {
72
73
  backgroundColor,
73
74
  imageBackgroundSource,
74
75
  imageBackgroundResizeMode,
76
+ testID,
75
77
  disableAppScale,
76
78
  disableImageBackgroundAnimation,
77
79
  } = this.props
80
+ testID = defaultStr(testID,"RN_SplashscreenComponent")
78
81
  logoWidth = defaultDecimal(logoWidth,150);
79
82
  logoHeight = defaultDecimal(logoHeight,250);
80
83
  const opacityClearToVisible = {
@@ -127,12 +130,13 @@ class AnimatedSplash extends React.Component {
127
130
  }
128
131
 
129
132
  return (
130
- <View style={[styles.container]}>
131
- {!animationDone && <View style={StyleSheet.absoluteFill} />}
133
+ <View style={[styles.container]} testID={testID} nativeID={testID}>
134
+ {!animationDone && <View style={StyleSheet.absoluteFill} testID={testID+"_Animation"}/>}
132
135
  <View style={styles.containerGlue}>
133
136
  {!animationDone && (
134
137
  <Animated.View
135
138
  style={_staticBackground(logoOpacity, backgroundColor)}
139
+ testID={testID+"_AnimationDone"}
136
140
  />
137
141
  )}
138
142
  {(animationDone || isNative) && <Component style={[!disableAppScale && appScale, opacityClearToVisible, styles.flex]}>
@@ -140,6 +144,7 @@ class AnimatedSplash extends React.Component {
140
144
  </Component>}
141
145
  {!animationDone && (
142
146
  <Animated.Image
147
+ testID={testID+"AnimateImage"}
143
148
  resizeMode={imageBackgroundResizeMode || "cover"}
144
149
  source={imageBackgroundSource}
145
150
  style={[disableImageBackgroundAnimation && _staticBackground(
@@ -153,9 +158,10 @@ class AnimatedSplash extends React.Component {
153
158
  />
154
159
  )}
155
160
  {!animationDone && (
156
- <View style={[StyleSheet.absoluteFill, styles.logoStyle]}>
161
+ <View testID={testID+"_LogoContainer"} style={[StyleSheet.absoluteFill, styles.logoStyle]}>
157
162
  {(
158
163
  <Animated.View
164
+ testID={testID+"_Logo"}
159
165
  style={_dynamicCustomComponentStyle(
160
166
  logoScale,
161
167
  logoOpacity,
package/src/index.js CHANGED
@@ -13,7 +13,6 @@ import {set as setSession,get as getSession} from "$session";
13
13
  import { showConfirm } from "$ecomponents/Dialog";
14
14
  import {close as closePreloader, isVisible as isPreloaderVisible} from "$epreloader";
15
15
  import SplashScreen from "$ecomponents/SplashScreen";
16
- import {notify} from "$ecomponents/Dialog";
17
16
  import {decycle} from "$cutils/json";
18
17
  import init from "$capp/init";
19
18
  import { setIsInitialized} from "$capp/utils";
@@ -21,6 +20,17 @@ import {isObj,isNonNullString,isPromise,defaultObj,defaultStr} from "$cutils";
21
20
  import {loadFonts} from "$ecomponents/Icon/Font";
22
21
  import appConfig from "$capp/config";
23
22
  import Preloader from "$preloader";
23
+ import {PreloaderProvider} from "$epreloader";
24
+ import BottomSheetProvider from "$ecomponents/BottomSheet/Provider";
25
+ import DialogProvider from "$ecomponents/Dialog/Provider";
26
+ import SimpleSelect from '$ecomponents/SimpleSelect';
27
+ import {Provider as AlertProvider} from '$ecomponents/Dialog/confirm/Alert';
28
+ import { DialogProvider as FormDataDialogProvider } from '$eform/FormData';
29
+ import {Portal } from 'react-native-paper';
30
+ import {PortalProvider,PortalHost } from '$ecomponents/Portal';
31
+ import ErrorBoundaryProvider from "$ecomponents/ErrorBoundary/Provider";
32
+ import notify, {notificationRef} from "$notify";
33
+ import DropdownAlert from '$ecomponents/Dialog/DropdownAlert';
24
34
 
25
35
  let MAX_BACK_COUNT = 1;
26
36
  let countBack = 0;
@@ -219,14 +229,25 @@ function App({init:initApp,initialRouteName:appInitialRouteName,getStartedRouteN
219
229
  }
220
230
  }
221
231
  >
222
- <Navigation
223
- initialRouteName = {defaultStr(hasGetStarted ? appInitialRouteName : getStartedRouteName,"Home")}
224
- state = {state}
225
- hasGetStarted = {hasGetStarted}
226
- onGetStart = {(e)=>{
227
- setState({...state,hasGetStarted:true})
228
- }}
229
- />
232
+ <PortalProvider>
233
+ <Portal.Host>
234
+ <PreloaderProvider/>
235
+ <DialogProvider responsive/>
236
+ <AlertProvider SimpleSelect={SimpleSelect}/>
237
+ <FormDataDialogProvider/>
238
+ <BottomSheetProvider/>
239
+ <DropdownAlert ref={notificationRef}/>
240
+ <ErrorBoundaryProvider/>
241
+ <Navigation
242
+ initialRouteName = {defaultStr(hasGetStarted ? appInitialRouteName : getStartedRouteName,"Home")}
243
+ state = {state}
244
+ hasGetStarted = {hasGetStarted}
245
+ onGetStart = {(e)=>{
246
+ setState({...state,hasGetStarted:true})
247
+ }}
248
+ />
249
+ </Portal.Host>
250
+ </PortalProvider>
230
251
  </NavigationContainer>
231
252
  </SplashScreen>);
232
253
  }
@@ -2,14 +2,14 @@ import React from '$react';
2
2
  import {StyleSheet} from 'react-native';
3
3
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
4
  import PropTypes from "prop-types";
5
- import {defaultObj,defaultStr,defaultNumber,defaultBool} from "$cutils";
5
+ import {defaultObj,defaultStr,defaultNumber,defaultBool,uniqid} from "$cutils";
6
6
  import View from "$ecomponents/View";
7
7
  import { useNavigation} from '$cnavigation';
8
8
  import Fab from "$layouts/Fab";
9
9
  import APP from "$capp";
10
10
  import AppBar,{createAppBarRef} from "$elayouts/AppBar";
11
- import ErrorBoundary from "$ecomponents/ErrorBoundary";
12
11
  import Portal from "$ecomponents/Portal";
12
+ import { FullWindowOverlay } from 'react-native-screens';
13
13
  import theme,{StyleProp} from "$theme";
14
14
  import StatusBar from "$ecomponents/StatusBar";
15
15
  import ScrollView from "$ecomponents/ScrollView";
@@ -108,57 +108,60 @@ export default function MainScreenScreenWithOrWithoutAuthContainer(props) {
108
108
  });
109
109
  }
110
110
  }, [title,subtitle]);
111
- const Wrapper = modal ? Portal : React.Fragment;
111
+ const Wrapper = modal ? PortalCP : React.Fragment;
112
+ const WrapperProps = modal? {screenName} : {};
112
113
  const fab = withFab ? <Fab
113
114
  {...fabProps}
114
115
  screenName={screenName}
115
116
  /> : null;
116
117
  const profilAvatar = typeof renderProfilAvatar =='function'? renderProfilAvatar(profilAvatarProps) : null;
117
- const child = <>
118
- {withStatusBar !== false ? <StatusBar/> : null}
119
- <ErrorBoundary testID={testID+"_ScreenLayoutErrorBoundary"}>
120
- <View testID={testID} {...containerProps} style={[styles.container,{backgroundColor},modal && styles.modal,containerProps.style]}>
121
- {appBar === false ? null : React.isValidElement(appBar)? state.AppBar : <AppBar
122
- testID={testID+'_AppBar'} {...appBarProps}
123
- backAction = {defaultVal(appBarProps.backAction,backAction)}
124
- elevation={defaultNumber(appBarProps.elevation,elevation)}
125
- withDrawer={withDrawer} options={options}
126
- ref={appBarRef} title={title}
127
- subtitle={subtitle}
128
- right = {withProfilAvatarOnAppBar && <View testID={testID+"_ProfilAvatar_Container"} {...profilAvatarContainerProps} style={[profilAvatarContainerProps.style,styles.profilAvatarContainer]} >
129
- {React.isValidElement(profilAvatar) && profilAvatar || null}
130
- </View> || null}
131
- />}
132
- {withScrollView !== false ? (
133
- <ScrollView
134
- testID = {testID+'_ScreenContentScrollView'}
135
- {...rest}
136
- contentContainerStyle={[contentContainerStyle]}
137
- style={[containerStyle,styles.container, style]}
138
- >
139
- {children}
140
- {fab}
141
- </ScrollView>
142
- ) : (
143
- <View testID={testID+'_ScreenContent'} {...rest} style={[containerStyle,styles.wrapper,styles.container, style]}>
144
- {children}
145
- {fab}
146
- </View>
147
- )}
148
- </View>
149
- </ErrorBoundary>
150
- </>
151
- return <Wrapper>
118
+ const portalId = uniqid("screeen-container-"+screenName);
119
+ return <Wrapper {...WrapperProps}>
152
120
  {renderChildren({
153
121
  containerProps : {
154
122
  ...authProps,
155
123
  required : authRequired,
156
124
  },
157
- children : child,
125
+ children : <View testID={testID} nativeID={portalId} {...containerProps} style={[styles.container,{backgroundColor},modal && styles.modal,containerProps.style]}>
126
+ {withStatusBar !== false ? <StatusBar/> : null}
127
+ {appBar === false ? null : React.isValidElement(appBar)? state.AppBar : <AppBar
128
+ testID={testID+'_AppBar'} {...appBarProps}
129
+ backAction = {defaultVal(appBarProps.backAction,backAction)}
130
+ elevation={defaultNumber(appBarProps.elevation,elevation)}
131
+ withDrawer={withDrawer} options={options}
132
+ ref={appBarRef} title={title}
133
+ subtitle={subtitle}
134
+ right = {withProfilAvatarOnAppBar && <View testID={testID+"_ProfilAvatar_Container"} {...profilAvatarContainerProps} style={[profilAvatarContainerProps.style,styles.profilAvatarContainer]} >
135
+ {React.isValidElement(profilAvatar) && profilAvatar || null}
136
+ </View> || null}
137
+ />}
138
+ {withScrollView !== false ? (
139
+ <ScrollView
140
+ testID = {testID+'_ScreenContentScrollView'}
141
+ {...rest}
142
+ contentContainerStyle={[contentContainerStyle]}
143
+ style={[containerStyle,styles.container, style]}
144
+ >
145
+ {children}
146
+ {fab}
147
+ </ScrollView>
148
+ ) : (
149
+ <View testID={testID+'_ScreenContent'} {...rest} style={[containerStyle,styles.wrapper,styles.container, style]}>
150
+ {children}
151
+ {fab}
152
+ </View>
153
+ )}
154
+ </View>,
158
155
  })}
159
156
  </Wrapper>
160
157
  }
161
158
 
159
+ const PortalCP = ({children,screenName})=>{
160
+ return <Portal>
161
+ {children}
162
+ </Portal>
163
+ }
164
+
162
165
  const styles = StyleSheet.create({
163
166
  container: {
164
167
  flex: 1,
@@ -21,6 +21,7 @@ import theme from "$theme";
21
21
  import cActions from "$cactions";
22
22
  import APP from "$capp/instance";
23
23
  import { generatedColumnsProperties } from "./utils";
24
+ import {isDocEditing,checkPrimaryKey} from "$ecomponents/Form";
24
25
  import i18n from "$i18n";
25
26
  import fetch from "$capi/fetch";
26
27
 
@@ -31,42 +32,6 @@ const DEFAULT_TABS_KEYS = "main-tabs";
31
32
 
32
33
  const TIMEOUT = 50;
33
34
 
34
- const checkPrimary = (data,f)=>{
35
- return !(!(f in data) || (data[f] == null) || (!data[f] && typeof data !=='number'));
36
- }
37
- /*** vérifie si le document passé en paramètre est éditable
38
- * @param {object} data la données à vérifier
39
- * @param {object| array} les champs sur lesquels se baser pour vérifier si la donénes est une mise à jour
40
- * @param {func} checkPrimaryKey la foncition permettant de vérifier s'il s'agit d'une clé primaire pour la données courante
41
- */
42
- export const isDocEditing = (data,fields,checkPrimaryKey)=>{
43
- if(!isObj(data) || !isObjOrArray(fields)) return false;
44
-
45
- let hasPrimaryFields = false;
46
- let hasValidated = true;
47
- for(let i in fields){
48
- const field = fields[i];
49
- if(typeof checkPrimaryKey =='function') {
50
- hasPrimaryFields = true;
51
- if(checkPrimaryKey({field,i,index:i,data}) === false){
52
- return false;
53
- }
54
- continue;
55
- }
56
- if(!isObj(field)) continue;
57
- hasPrimaryFields = true;
58
- const f = defaultStr(field.field,i);
59
- if(field.primaryKey === true){
60
- if(!checkPrimary(data,f)){
61
- hasValidated = false;
62
- }
63
- }
64
- }
65
- if(hasPrimaryFields){
66
- return hasValidated;
67
- }
68
- return false;
69
- }
70
35
 
71
36
  export default class TableDataScreenComponent extends FormDataScreen{
72
37
  constructor(props){
@@ -280,6 +245,9 @@ export default class TableDataScreenComponent extends FormDataScreen{
280
245
  currentField.disabled = true;
281
246
  }
282
247
  }
248
+ if(field.primaryKey ===true){
249
+ this.primaryKeyFields[columnField] = true;
250
+ }
283
251
  const isPrimary = this.primaryKeyFields[columnField] && true || false;
284
252
  const f = prepareCb(cArgs);
285
253
  if(f === false) {
@@ -536,7 +504,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
536
504
  const isDocEditingCb = typeof this.props.isDocEditing =='function'? this.props.isDocEditing : typeof this.props.isDocUpdate =='function'? this.props.isDocUpdate : undefined;
537
505
  if(!isDocEditingCb){
538
506
  if(isDocEditing(data,this.primaryKeyFields,({index:field,data})=>{
539
- return checkPrimary(data,field);
507
+ return checkPrimaryKey(data,field);
540
508
  })) return true;
541
509
  } else {
542
510
  return isDocEditingCb(data,{context:this});
@@ -276,4 +276,5 @@ export const getScreenName = (screenName)=>{
276
276
  screenName = defaultStr(screenName.table,screenName.tableName);
277
277
  }
278
278
  return getTableDataRouteName(screenName);
279
- }
279
+ }
280
+