@fto-consult/expo-ui 5.7.0 → 5.7.2
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 +3 -3
- package/src/components/Chart/appexChart/index.html +14 -14
- package/src/components/Chart/appexChart/index.js +1 -1
- package/src/components/Color/ColorPicker.js +31 -17
- package/src/components/Datagrid/Accordion/Row.js +3 -2
- package/src/components/Datagrid/Common/Common.js +35 -5
- package/src/components/Datagrid/SWRDatagrid.js +7 -2
- package/src/components/Form/Fields/Field.js +2 -4
- package/src/components/Form/Fields/IDField.js +115 -0
- package/src/components/Form/Fields/index.js +14 -4
- package/src/components/Form/FormData/FormData.js +3 -3
- package/src/components/Form/FormData/componentsTypes.js +43 -31
- package/src/components/Form/FormData/utils.js +1 -8
- package/src/components/Form/index.js +1 -1
- package/src/components/Icon/IconButton.js +0 -1
- package/src/components/TableLink/index.js +1 -1
- package/src/layouts/Screen/TableData.js +2 -1
- package/src/components/Chart/appexChart/appexchart.3.5.html +0 -14
- package/src/components/Form/Fields/IdField.js +0 -131
- package/src/components/Form/Fields/PieceField.js +0 -136
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { Component } from "$react";
|
|
2
2
|
import {normalize,RGB_MAX,HUE_MAX,SV_MAX,hexToRgb} from "$theme/colors";
|
|
3
|
-
import {extendObj} from "$cutils";
|
|
3
|
+
import {extendObj,defaultStr,isNonNullString,defaultObj,isObj} from "$cutils";
|
|
4
4
|
import View from "$ecomponents/View";
|
|
5
5
|
import {
|
|
6
6
|
Animated,
|
|
@@ -15,7 +15,7 @@ import srcWheel from './assets/color-wheel.png';
|
|
|
15
15
|
import srcSlider from './assets/black-gradient.png';
|
|
16
16
|
import srcSliderRotated from './assets/black-gradient-rotated.png';
|
|
17
17
|
|
|
18
|
-
import {Colors} from "$theme";
|
|
18
|
+
import theme,{Colors} from "$theme";
|
|
19
19
|
import TextField from "$ecomponents/TextField";
|
|
20
20
|
|
|
21
21
|
|
|
@@ -398,7 +398,7 @@ export default class ColorPickerComponent extends Component {
|
|
|
398
398
|
}
|
|
399
399
|
renderSwatches () {
|
|
400
400
|
this.swatches = this.props.palette.map((c,i) => (
|
|
401
|
-
<View style={[styles.swatch,{backgroundColor:c}]} key={'S'+i} hitSlop={this.props.swatchesHitSlop}>
|
|
401
|
+
<View testID={"RN_ColorPicker_SWATCHES"} style={[styles.swatch,theme.styles.cursorPointer,{backgroundColor:c}]} key={'S'+i} hitSlop={this.props.swatchesHitSlop}>
|
|
402
402
|
<TouchableWithoutFeedback onPress={x=>this.onSwatchPress(c,i)} hitSlop={this.props.swatchesHitSlop}>
|
|
403
403
|
<Animated.View style={[styles.swatchTouch,{backgroundColor:c,transform:[{scale:this.swatchAnim[i].interpolate({inputRange:[0,0.5,1],outputRange:[0.666,1,0.666]})}]}]} />
|
|
404
404
|
</TouchableWithoutFeedback>
|
|
@@ -407,8 +407,8 @@ export default class ColorPickerComponent extends Component {
|
|
|
407
407
|
}
|
|
408
408
|
renderDiscs () {
|
|
409
409
|
this.disc = (`1`).repeat(this.props.discreteLength).split('').map((c,i) => (
|
|
410
|
-
<View style={[styles.swatch,{backgroundColor:this.state.hueSaturation}]} key={'D'+i} hitSlop={this.props.swatchesHitSlop}>
|
|
411
|
-
<TouchableWithoutFeedback onPress={x=>this.onDiscPress(c,i)} hitSlop={this.props.swatchesHitSlop}>
|
|
410
|
+
<View testID={"RN_ColorPicker_DISC"} style={[styles.swatch,{backgroundColor:this.state.hueSaturation}]} key={'D'+i} hitSlop={this.props.swatchesHitSlop}>
|
|
411
|
+
<TouchableWithoutFeedback style={[theme.styles.cursorPointer]} onPress={x=>this.onDiscPress(c,i)} hitSlop={this.props.swatchesHitSlop}>
|
|
412
412
|
<Animated.View style={[styles.swatchTouch,{backgroundColor:this.state.hueSaturation,transform:[{scale:this.discAnim[i].interpolate({inputRange:[0,0.5,1],outputRange:[0.666,1,0.666]})}]}]}>
|
|
413
413
|
<View style={[styles.wheelImg,{backgroundColor:'#000',opacity:1-(i>=9?1:(i*11/100))}]}></View>
|
|
414
414
|
</Animated.View>
|
|
@@ -430,6 +430,7 @@ export default class ColorPickerComponent extends Component {
|
|
|
430
430
|
disabled,
|
|
431
431
|
editable,
|
|
432
432
|
row,
|
|
433
|
+
testID : customTestId,
|
|
433
434
|
} = this.props
|
|
434
435
|
const swatches = !!(this.props.swatches || swatchesOnly)
|
|
435
436
|
const hsv = hsvToHex(this.color), hex = hsvToHex(this.color.h,this.color.s,100)
|
|
@@ -483,34 +484,47 @@ export default class ColorPickerComponent extends Component {
|
|
|
483
484
|
marginBottom:row?0:margin,
|
|
484
485
|
}
|
|
485
486
|
// console.log('RENDER >>',row,thumbSize,sliderSize)
|
|
487
|
+
const testID = defaultStr(customTestId,"RN_ColorPickerContainer");
|
|
488
|
+
const hasHex = Colors.isValid(hex);
|
|
489
|
+
const contrastColor = hasHex ? Colors.getContrast(hex) : undefined;
|
|
490
|
+
const restProps = hasHex ? {
|
|
491
|
+
color : contrastColor,
|
|
492
|
+
backgroundColor : hex,
|
|
493
|
+
style : [{
|
|
494
|
+
color : contrastColor,
|
|
495
|
+
backgroundColor : hex,
|
|
496
|
+
}]
|
|
497
|
+
} : {};
|
|
486
498
|
return (
|
|
487
|
-
<View testID=
|
|
488
|
-
<View style={[styles.root,row?{flexDirection:'row'}:{},style]}>
|
|
489
|
-
{ swatches && !swatchesLast && <View style={[styles.swatches,swatchStyle,swatchFirstStyle]} key={'SW'}>{ this.swatches }</View> }
|
|
490
|
-
{ !swatchesOnly && <View style={[styles.wheel]} key={'$1'} onLayout={this.onSquareLayout}>
|
|
499
|
+
<View testID={testID}>
|
|
500
|
+
<View testID={`${testID}_RowContainer`} style={[styles.root,row?{flexDirection:'row'}:{},style]}>
|
|
501
|
+
{ swatches && !swatchesLast && <View testID={`${testID}_SwatchestLast`} style={[styles.swatches,swatchStyle,swatchFirstStyle]} key={'SW'}>{ this.swatches }</View> }
|
|
502
|
+
{ !swatchesOnly && <View testID={`${testID}_SwatchesOnly`} style={[styles.wheel]} key={'$1'} onLayout={this.onSquareLayout}>
|
|
491
503
|
{ this.wheelWidth>0 && <View style={[{padding:thumbSize/2,width:this.wheelWidth,height:this.wheelWidth}]}>
|
|
492
|
-
<View style={[styles.wheelWrap]}>
|
|
493
|
-
<Image style={styles.wheelImg} source={srcWheel} />
|
|
494
|
-
<Animated.View style={[styles.wheelThumb,wheelThumbStyle,Elevations[4],{pointerEvents:'none'}]} />
|
|
495
|
-
<View style={[styles.cover]} onLayout={this.onWheelLayout} {...wheelPanHandlers} ref={r => { this.wheel = r }}></View>
|
|
504
|
+
<View style={[styles.wheelWrap,theme.styles.cursorPointer]} testID={`${testID}_WheelWrap`}>
|
|
505
|
+
<Image testID={testID+"_WheelImg"} style={styles.wheelImg} source={srcWheel} />
|
|
506
|
+
<Animated.View testID={testID+"WheelThumb"} style={[styles.wheelThumb,wheelThumbStyle,Elevations[4],{pointerEvents:'none'}]} />
|
|
507
|
+
<View testID={testID+"_WheelWrapLayout"} style={[styles.cover]} onLayout={this.onWheelLayout} {...wheelPanHandlers} ref={r => { this.wheel = r }}></View>
|
|
496
508
|
</View>
|
|
497
509
|
</View> }
|
|
498
510
|
</View> }
|
|
499
|
-
{ !swatchesOnly && !sliderHidden && (discrete ? <View style={[styles.swatches,swatchStyle]} key={'$2'}>{ this.disc }</View> : <View style={[styles.slider,sliderStyle]} key={'$2'}>
|
|
500
|
-
<View
|
|
511
|
+
{ !swatchesOnly && !sliderHidden && (discrete ? <View testID={`${testID}_SwatchesDiscrete`} style={[styles.swatches,swatchStyle]} key={'$2'}>{ this.disc }</View> : <View style={[styles.slider,sliderStyle]} key={'$2'}>
|
|
512
|
+
<View testID={testID+"_WheelGrad"} sstyle={[styles.grad,{backgroundColor:hex}]}>
|
|
501
513
|
<Image style={styles.sliderImg} source={row?srcSliderRotated:srcSlider} resizeMode="stretch" />
|
|
502
514
|
</View>
|
|
503
515
|
<Animated.View style={[styles.sliderThumb,sliderThumbStyle,Elevations[4],{pointerEvents:'none'}]} />
|
|
504
516
|
<View style={[styles.cover]} onLayout={this.onSliderLayout} {...sliderPanHandlers} ref={r => { this.slider = r }}></View>
|
|
505
517
|
</View>) }
|
|
506
|
-
{ swatches && swatchesLast && <View style={[styles.swatches,swatchStyle]} key={'SW'}>{ this.swatches }</View> }
|
|
518
|
+
{ swatches && swatchesLast && <View testID={`${testID}_SwatchesList`} style={[styles.swatches,swatchStyle]} key={'SW'}>{ this.swatches }</View> }
|
|
507
519
|
<TextField
|
|
520
|
+
testID={`${testID}_ColorPickerInput`}
|
|
508
521
|
enableCopy
|
|
509
522
|
label = ''
|
|
510
523
|
editable = {editable}
|
|
511
524
|
disabled = {disabled}
|
|
512
525
|
defaultValue = {hex}
|
|
513
|
-
|
|
526
|
+
{...restProps}
|
|
527
|
+
style = {[styles.textInput,restProps.style]}
|
|
514
528
|
onChangeText = {(value)=>{
|
|
515
529
|
if(Colors.isHex(value)){
|
|
516
530
|
this.update(value);
|
|
@@ -9,6 +9,7 @@ import theme from "$theme"
|
|
|
9
9
|
import {styles as rStyles} from "../utils";
|
|
10
10
|
import {getSelectedBackgroundColor} from "../Actions/Header";
|
|
11
11
|
import Swipeable from 'react-native-gesture-handler/Swipeable';
|
|
12
|
+
import {isMobileNative} from "$platform";
|
|
12
13
|
|
|
13
14
|
const DatagridAccordionRow = React.forwardRef((props,ref)=>{
|
|
14
15
|
const {selectable,rowKey,
|
|
@@ -166,7 +167,7 @@ const DatagridAccordionRow = React.forwardRef((props,ref)=>{
|
|
|
166
167
|
_rP.style,rowProps.style,
|
|
167
168
|
styles.container,
|
|
168
169
|
numColumns > 1 && {width:'99%'},
|
|
169
|
-
selected && styles.containerSelected,
|
|
170
|
+
//selected && !hasAvatar && styles.containerSelected,
|
|
170
171
|
styles.bordered,
|
|
171
172
|
wrapperStyle,
|
|
172
173
|
style,
|
|
@@ -273,7 +274,7 @@ const styles = StyleSheet.create({
|
|
|
273
274
|
container : {
|
|
274
275
|
marginVertical : 10,
|
|
275
276
|
paddingVertical : 5,
|
|
276
|
-
paddingHorizontal : 15,
|
|
277
|
+
paddingHorizontal : 10,// isMobileNative()? 15:10,
|
|
277
278
|
marginHorizontal : 5,
|
|
278
279
|
flexWrap : 'nowrap',
|
|
279
280
|
justifyContent : 'center',
|
|
@@ -2686,11 +2686,12 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
2686
2686
|
return defaultNumber(this.sectionListDataSize.current)
|
|
2687
2687
|
}
|
|
2688
2688
|
prepareData(args,cb){
|
|
2689
|
-
let {pagination,config,aggregatorFunction:customAggregatorFunction,displayOnlySectionListHeaders:cdisplayOnlySectionListHeaders,data,force,sectionListColumns,updateFooters} = defaultObj(args);
|
|
2689
|
+
let {pagination,config,aggregatorFunction:customAggregatorFunction,displayOnlySectionListHeaders:cdisplayOnlySectionListHeaders,data,force,sectionListColumns,sectionListCollapsedStates,updateFooters} = defaultObj(args);
|
|
2690
2690
|
cb = typeof cb ==='function'? cb : typeof args.cb == 'function'? args.cb : undefined;
|
|
2691
2691
|
config = isObj(config) && Object.size(config,true)? config : this.getConfig();
|
|
2692
2692
|
const aggregatorFunction = isNonNullString(customAggregatorFunction) && customAggregatorFunction in this.aggregatorFunctions ? this.aggregatorFunctions[customAggregatorFunction] : this.getActiveAggregatorFunction();
|
|
2693
2693
|
sectionListColumns = isObj(sectionListColumns) ? sectionListColumns : this.state.sectionListColumns;
|
|
2694
|
+
sectionListCollapsedStates = isObj(sectionListCollapsedStates)? sectionListCollapsedStates: defaultObj(this.state.sectionListCollapsedStates);
|
|
2694
2695
|
const displayOnlySectionListHeaders = typeof cdisplayOnlySectionListHeaders == 'boolean'?cdisplayOnlySectionListHeaders : this.state.displayOnlySectionListHeaders;
|
|
2695
2696
|
let isArr = Array.isArray(data);
|
|
2696
2697
|
//let push = (d,index) => isArr ? newData.push(d) : newData[index] = d;
|
|
@@ -2808,7 +2809,7 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
2808
2809
|
} else if(force){
|
|
2809
2810
|
this.setSelectedRows();
|
|
2810
2811
|
}
|
|
2811
|
-
const state = {data,displayOnlySectionListHeaders,aggregatorFunction:aggregatorFunction.code};
|
|
2812
|
+
const state = {data,displayOnlySectionListHeaders,sectionListCollapsedStates,aggregatorFunction:aggregatorFunction.code};
|
|
2812
2813
|
if((cb)){
|
|
2813
2814
|
cb(state);
|
|
2814
2815
|
}
|
|
@@ -2821,7 +2822,7 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
2821
2822
|
const config = isObj(args.config) && Object.size(args.config,true)? args.config : this.getConfig();
|
|
2822
2823
|
const displayGroupLabels = "displayGroupLabels" in config? config.displayGroupLabels : true;
|
|
2823
2824
|
const displayGroupLabelsSeparator = typeof config.displayGroupLabelsSeparator =='string'? config.displayGroupLabelsSeparator : arrayValueSeparator;
|
|
2824
|
-
const {fields
|
|
2825
|
+
const {fields} = args;
|
|
2825
2826
|
const d = [];
|
|
2826
2827
|
Object.map(fields,(field,i)=>{
|
|
2827
2828
|
const txt = this.renderRowCell({
|
|
@@ -2832,10 +2833,11 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
2832
2833
|
columnField : defaultStr(field.field,i),
|
|
2833
2834
|
});
|
|
2834
2835
|
if(!isNonNullString(txt) && typeof txt !=='number') return;
|
|
2835
|
-
|
|
2836
|
+
const labelText = defaultStr(field.label,field.text);
|
|
2837
|
+
if(!displayGroupLabels || !labelText){
|
|
2836
2838
|
d.push(txt);
|
|
2837
2839
|
} else {
|
|
2838
|
-
d.push("{0} : {1}".sprintf(
|
|
2840
|
+
d.push("{0} : {1}".sprintf(labelText,txt))
|
|
2839
2841
|
}
|
|
2840
2842
|
});
|
|
2841
2843
|
return d.length ? d.join(displayGroupLabelsSeparator) : undefined;
|
|
@@ -2846,6 +2848,22 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
2846
2848
|
getFlashListItemType(item){
|
|
2847
2849
|
return typeof item === "string" || isObj(item) && item.isSectionListHeader === true ? "sectionHeader" : "row";;
|
|
2848
2850
|
}
|
|
2851
|
+
getSectionListCollapsedStates(){
|
|
2852
|
+
return defaultObj(this.state.sectionListCollapsedStates)
|
|
2853
|
+
}
|
|
2854
|
+
isSectionListCollapsed(sectionListKey){
|
|
2855
|
+
return isNonNullString(sectionListKey)? !!this.getSectionListCollapsedStates()[sectionListKey] : false;
|
|
2856
|
+
}
|
|
2857
|
+
toggleSectionListCollapsedState(sectionKey){
|
|
2858
|
+
const s = getSectionListCollapsedStates;
|
|
2859
|
+
if(!isNonNullString(sectionKey)) return;
|
|
2860
|
+
s[sectionKey] = !!!s[sectionKey];
|
|
2861
|
+
setTimeout(()=>{
|
|
2862
|
+
this.setIsLoading(true,()=>{
|
|
2863
|
+
this.setState({sectionListCollapsedStates:{...s}});
|
|
2864
|
+
},true);
|
|
2865
|
+
},TIMEOUT)
|
|
2866
|
+
}
|
|
2849
2867
|
/****permet de faire le rendu flashlist */
|
|
2850
2868
|
renderFlashListItem(args){
|
|
2851
2869
|
if(!this.hasSectionListData()) return null;
|
|
@@ -2904,7 +2922,19 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
2904
2922
|
});
|
|
2905
2923
|
}
|
|
2906
2924
|
}
|
|
2925
|
+
const isCollapsed = this.isSectionListCollapsed(key);
|
|
2907
2926
|
return <View testID={testID+"_ContentContainer"} style={[theme.styles.w100,isA && this.state.displayOnlySectionListHeaders && {borderTopColor:theme.colors.divider,borderTopWidth:1},isA ? [theme.styles.ph2,theme.styles.pt1] : [theme.styles.pt1,theme.styles.noPadding,theme.styles.noMargin],theme.styles.justifyContentCenter,theme.styles.alignItemsCenter,theme.styles.pb1,!cells && theme.styles.ml1,theme.styles.mr1,cStyle]}>
|
|
2927
|
+
{false && <View testID={testID+"_LabelAndCollapsedContainer"} style={[theme.styles.w100,theme.styles.row,theme.styles.alignItemsCenter,theme.styles.justifyContentStart]}>
|
|
2928
|
+
<Icon
|
|
2929
|
+
name = {isCollapsed?"chevron-up":"chevron-right"}
|
|
2930
|
+
color = {theme.colors.primaryOnSurface}
|
|
2931
|
+
style = {[theme.styles.noMargin,theme.styles.noPadding]}
|
|
2932
|
+
size = {25}
|
|
2933
|
+
onPress = {(e)=>{
|
|
2934
|
+
this.toggleSectionListCollapsedState(key);
|
|
2935
|
+
}}
|
|
2936
|
+
/>
|
|
2937
|
+
</View>}
|
|
2908
2938
|
<Label testID={testID+"_Label"} splitText numberOfLines={3} textBold style={[theme.styles.w100,{color:theme.colors.primaryOnSurface,fontSize:isA?15 :16},lStyle,theme.styles.ph1]}>{label}</Label>
|
|
2909
2939
|
{cells ? <View testID={testID+"_TableRow"} style = {[theme.styles.w100,theme.styles.row,isA && theme.styles.pt1,theme.styles.alignItemsFlexStart,this.isAccordion() && theme.styles.rowWrap]}
|
|
2910
2940
|
>{cells}</View> : null}
|
|
@@ -93,6 +93,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
|
93
93
|
autoSort,
|
|
94
94
|
fetchOptions:customFetchOptions,
|
|
95
95
|
handleQueryLimit,
|
|
96
|
+
handlePagination,
|
|
96
97
|
onFetchData,
|
|
97
98
|
beforeFetchData,
|
|
98
99
|
sort,
|
|
@@ -162,7 +163,8 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
|
162
163
|
const totalRef = React.useRef(0);
|
|
163
164
|
const isFetchingRef = React.useRef(false);
|
|
164
165
|
const pageRef = React.useRef(1);
|
|
165
|
-
const
|
|
166
|
+
const canHandlePagination = handlePagination !== false ? true : false;
|
|
167
|
+
const canHandleLimit = handleQueryLimit !== false && canHandlePagination ? true : false;
|
|
166
168
|
const limitRef = React.useRef(!canHandleLimit ?0 : defaultNumber(getSessionData("limit"),500));
|
|
167
169
|
const isInitializedRef = React.useRef(false);
|
|
168
170
|
testID = defaultStr(testID,"RNSWRDatagridComponent");
|
|
@@ -191,7 +193,8 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
|
191
193
|
delete opts.page;
|
|
192
194
|
delete opts.offset;
|
|
193
195
|
}
|
|
194
|
-
const fetchCB = (
|
|
196
|
+
const fetchCB = (fArgs)=>{
|
|
197
|
+
let {data,total} = (Array.isArray(fArgs) ? {data:fArgs,total:fArgs.length} : isObj(fArgs)? fArgs : {data:[],total:0});
|
|
195
198
|
totalRef.current = total;
|
|
196
199
|
dataRef.current = data;
|
|
197
200
|
const dd = Object.size(data);
|
|
@@ -254,6 +257,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
|
254
257
|
refresh();
|
|
255
258
|
}
|
|
256
259
|
const canPaginate = ()=>{
|
|
260
|
+
if(!canHandlePagination) return false;
|
|
257
261
|
if(canHandleLimit && typeof totalRef.current !=='number' || typeof pageRef.current !='number' || typeof limitRef.current !='number') return false;
|
|
258
262
|
if(limitRef.current <= 0) return false;
|
|
259
263
|
return true;
|
|
@@ -455,6 +459,7 @@ SWRDatagridComponent.displayName = "SWRDatagridComponent";
|
|
|
455
459
|
|
|
456
460
|
SWRDatagridComponent.propTypes = {
|
|
457
461
|
...Datagrid.propTypes,
|
|
462
|
+
handlePagination : PropTypes.bool, //spécifie si le datagrid prendra en compte la pagination
|
|
458
463
|
/*** le nom de la colonne de trie par défaut */
|
|
459
464
|
defaultSortColumn : PropTypes.string,
|
|
460
465
|
fetchPath : PropTypes.string,
|
|
@@ -623,10 +623,8 @@ export default class Field extends AppComponent {
|
|
|
623
623
|
if(!this.canValidate) return;
|
|
624
624
|
let {keyboardEvents,onKeyEvent} = this.props;
|
|
625
625
|
const formInstance = this.getForm();
|
|
626
|
-
const
|
|
627
|
-
|
|
628
|
-
arg.data = formInstance.getData();
|
|
629
|
-
}
|
|
626
|
+
const data = formInstance ? formInstance.getData() : {};
|
|
627
|
+
const arg = {key,event,formInstance,field:this.name,formName:this.getFormName(),value:this.getValidRule(),validValue:this.getValidValue(data),data,context:this,isFormField:true,formInstance};
|
|
630
628
|
let handler = undefined;
|
|
631
629
|
if(isObj(keyboardEvents)){
|
|
632
630
|
handler = keyboardEvents[key];
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import TextField from "./TextField";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { UPPER_CASE } from "$clib/validator";
|
|
4
|
+
import {isNonNullString,defaultStr,isPromise} from "$cutils";
|
|
5
|
+
import React from "$react";
|
|
6
|
+
import { ActivityIndicator } from "react-native-paper";
|
|
7
|
+
|
|
8
|
+
export default class FormIDField extends TextField {
|
|
9
|
+
constructor(props){
|
|
10
|
+
super(props)
|
|
11
|
+
this.autobind();
|
|
12
|
+
}
|
|
13
|
+
UNSAFE_componentWillReceiveProps(nextProps){
|
|
14
|
+
this.newFieldIdValue = undefined;
|
|
15
|
+
return super.UNSAFE_componentWillReceiveProps(nextProps);
|
|
16
|
+
}
|
|
17
|
+
componentDidMount(){
|
|
18
|
+
super.componentDidMount();
|
|
19
|
+
this.fetchNewId(false);
|
|
20
|
+
}
|
|
21
|
+
handleCheckIdError(msg,errorCb){
|
|
22
|
+
this.canCheckAgain = false;
|
|
23
|
+
this.hasError = true;
|
|
24
|
+
if(isNonNullString(msg)) this.onNoValidate(msg,undefined,this,null,null);
|
|
25
|
+
if(isFunction(errorCb)){
|
|
26
|
+
errorCb(e);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/*** met à jour la données du numéro de piece */
|
|
31
|
+
fetchNewId(focus){
|
|
32
|
+
const data = defaultObj(this.props.data);
|
|
33
|
+
if(!isNonNullString(this.name)) return undefined;
|
|
34
|
+
const cb = (value)=>{
|
|
35
|
+
if(isNonNullString(value)){
|
|
36
|
+
this.newFieldIdValue = value;
|
|
37
|
+
this.validate({value});
|
|
38
|
+
if(focus) this.focus();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if(isNonNullString(data[this.name])){
|
|
42
|
+
cb(data[this.name]);
|
|
43
|
+
return data[this.name]
|
|
44
|
+
}
|
|
45
|
+
setTimeout(()=>{
|
|
46
|
+
const fId = typeof this.props.fetchNewId =='function'? this.props.fetchNewId({...this.props,data,columnField:this.name}) : null;
|
|
47
|
+
if(isPromise(fId)){
|
|
48
|
+
return fId.then(cb).catch(e=>{
|
|
49
|
+
console.log(e," fetching new piece id ",this.name);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return cb(fId);
|
|
53
|
+
},10);
|
|
54
|
+
}
|
|
55
|
+
/*** retourne la valeur validée */
|
|
56
|
+
getValidValue(data){
|
|
57
|
+
const validValue = super.getValidValue(data);
|
|
58
|
+
console.log(data, " is valid value ",data);
|
|
59
|
+
if(!isNonNullString(this.name)) return validValue;
|
|
60
|
+
data[this.name] = defaultStr(data[this.name],validValue,this.newFieldIdValue);
|
|
61
|
+
return validValue;
|
|
62
|
+
}
|
|
63
|
+
isValidRuleDynamic(){
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
isTextField(){
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
componentDidUpdate(){
|
|
70
|
+
if(!isNonNullString(this.newFieldIdValue)){
|
|
71
|
+
this.fetchNewId();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
_render(props,setRef){
|
|
75
|
+
delete props.validType;
|
|
76
|
+
if(isNonNullString(this.name) && isObj(props.data) && isNonNullString(props.data[this.name])){
|
|
77
|
+
props.disabled = true;
|
|
78
|
+
props.validType = UPPER_CASE;
|
|
79
|
+
props.defaultValue = props.data[this.name];
|
|
80
|
+
} else {
|
|
81
|
+
props.validType = 'required|'+UPPER_CASE;
|
|
82
|
+
}
|
|
83
|
+
if(typeof props.minLength !=='number'){
|
|
84
|
+
props.minLength = 2;
|
|
85
|
+
}
|
|
86
|
+
const defValue = props.defaultValue = isNonNullString(props.defaultValue)? props.defaultValue : isNonNullString(this.newFieldIdValue)? this.newFieldIdValue : undefined;
|
|
87
|
+
props.validRule = props.validType;
|
|
88
|
+
props.contentContainerProps = Object.assign({},props.contentContainerProps)
|
|
89
|
+
props.contentContainerProps.pointerEvents = defaultStr(props.contentContainerProps.pointerEvents,"auto");
|
|
90
|
+
props.enableCopy = typeof props.enableCopy ==='boolean'? props.enableCopy : (props.defaultValue || this.newFieldIdValue ? true : false);
|
|
91
|
+
const {right} = props;
|
|
92
|
+
props.editable = typeof props.editable =='boolean'? props.editable : typeof props.disabled ==='boolean' ? !!!props.disabled : typeof props.readOnly =="boolean"? !!!props.disabled : false;
|
|
93
|
+
props.right = (props)=>{
|
|
94
|
+
const r = typeof right =='function'? right (props) : React.isValidElement(right)? right : null;
|
|
95
|
+
if(!defValue){
|
|
96
|
+
return <>{r}<ActivityIndicator
|
|
97
|
+
{...props}
|
|
98
|
+
style = {[props.style,{marginRight:10}]}
|
|
99
|
+
/></>
|
|
100
|
+
}
|
|
101
|
+
return r;
|
|
102
|
+
}
|
|
103
|
+
this.setValidRule(props.validType);
|
|
104
|
+
return super._render(props,setRef);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/*** le principe est de générer une id et vérifier l'existance deans la bd, jusqu'à retourner un
|
|
109
|
+
* qui n'existe pas en bd
|
|
110
|
+
*/
|
|
111
|
+
FormIDField.propTypes = {
|
|
112
|
+
...TextField.propTypes,
|
|
113
|
+
fetchNewId : PropTypes.func, ///({data,...props}), la fonction permettant de fetch un newId pour la données
|
|
114
|
+
}
|
|
115
|
+
FormIDField.filter = false;//disabled on filter component
|
|
@@ -6,7 +6,7 @@ import Checkbox from "./Checkbox";
|
|
|
6
6
|
import SelectTableData from "./SelectTableData";
|
|
7
7
|
import SelectCurrency from "./SelectCurrency";
|
|
8
8
|
//import IdField from "./IdField";
|
|
9
|
-
|
|
9
|
+
import IDField from "./IDField";
|
|
10
10
|
import Slider from "./Slider";
|
|
11
11
|
import ColorPicker from "./Color";
|
|
12
12
|
import Date from "./Date";
|
|
@@ -34,7 +34,7 @@ const defFormFields = {
|
|
|
34
34
|
,Switch
|
|
35
35
|
,Checkbox
|
|
36
36
|
//,IdField
|
|
37
|
-
|
|
37
|
+
,IDField
|
|
38
38
|
,Slider
|
|
39
39
|
,ColorPicker
|
|
40
40
|
,Date
|
|
@@ -66,7 +66,7 @@ export {
|
|
|
66
66
|
,Switch
|
|
67
67
|
,Checkbox
|
|
68
68
|
//,IdField
|
|
69
|
-
|
|
69
|
+
,IDField
|
|
70
70
|
,Slider
|
|
71
71
|
,ColorPicker
|
|
72
72
|
,ColorPicker as Color
|
|
@@ -76,4 +76,14 @@ export {
|
|
|
76
76
|
,Tel
|
|
77
77
|
,SelectDateFormat
|
|
78
78
|
,Html
|
|
79
|
-
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export const extendFields = (fields)=>{
|
|
82
|
+
Object.map(fields,(f,i)=>{
|
|
83
|
+
if(React.isComponent(f)){
|
|
84
|
+
defFormFields[i] = f;
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export const extendFormFields = extendFields;
|
|
@@ -10,7 +10,7 @@ import PropTypes from "prop-types";
|
|
|
10
10
|
import {renderActions} from "$ecomponents/Dialog/utils";
|
|
11
11
|
//import {isDocUpdate} from "$database/utils";
|
|
12
12
|
import {handleBeforeSaveCallback} from "./utils";
|
|
13
|
-
import
|
|
13
|
+
import getComponentFromType from "./componentsTypes";
|
|
14
14
|
import { keyboardShortcuts } from "../utils";
|
|
15
15
|
import appConfig from "$capp/config";
|
|
16
16
|
|
|
@@ -191,9 +191,9 @@ export default class FormDataComponent extends AppComponent{
|
|
|
191
191
|
content.push(<Divider key = {index} style={theme.styles.w100}/>)
|
|
192
192
|
} else if(isObj(field) && field.form !== false) {
|
|
193
193
|
const name = defaultStr(field.name,field.field,index);
|
|
194
|
-
const type = defaultStr(field.jsType,field.type,"text").trim().toLowerCase().replaceAll("_","");
|
|
194
|
+
const type = defaultStr(field.jsType,field.type,"text").trim().toLowerCase().replaceAll(" ","").replaceAll("-","").replaceAll("_","");
|
|
195
195
|
const isDate = (type.contains('date') || type.contains('time'));
|
|
196
|
-
const Component =
|
|
196
|
+
const Component = getComponentFromType(defaultStr(field.jsType,field.type,"text"));
|
|
197
197
|
let {defaultValue,useDefaultValueFromData,primaryKey,hidden,renderFormDataField,getMediaQueryStyle,printLabels,queryLimit,selected,value,dataFilesInterest,perm,ignore,form,responsiveProps:customResponsiveProps,...rest} = field;
|
|
198
198
|
rest = Object.assign({},rest);
|
|
199
199
|
delete rest.import;
|
|
@@ -4,38 +4,49 @@ import Fields from "../Fields";
|
|
|
4
4
|
import i18n from "$i18n";
|
|
5
5
|
import React from "$react";
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
7
|
+
|
|
8
|
+
export const getComponentTypes = ()=>{
|
|
9
|
+
return {
|
|
10
|
+
id : Fields.IDField,
|
|
11
|
+
...Fields,
|
|
12
|
+
selecttabledata : Fields.SelectTableData,
|
|
13
|
+
idfield : Fields.IdField,
|
|
14
|
+
select : Fields.SelectField,
|
|
15
|
+
switch : Fields.Switch,
|
|
16
|
+
selectcountry : Fields.SelectCountry,
|
|
17
|
+
selectdateformat : Fields.SelectDateFormat,
|
|
18
|
+
selectcurrency : Fields.SelectCurrency,
|
|
19
|
+
currencyformat : Fields.CurrencyFormat,
|
|
20
|
+
dateformat : Fields.SelectDateFormat,
|
|
21
|
+
date : Fields.Date,
|
|
22
|
+
time : Fields.Time,
|
|
23
|
+
datetime : Fields.DateTime,
|
|
24
|
+
date2time : Fields.DateTime,
|
|
25
|
+
checkbox : Fields.Checkbox,
|
|
26
|
+
slider : Fields.Slider,
|
|
27
|
+
color : Fields.ColorPicker,
|
|
28
|
+
tel : Fields.Tel,
|
|
29
|
+
html : Fields.Html,
|
|
30
|
+
datafile : Fields.DataFile,
|
|
31
|
+
image : Fields.Image,
|
|
32
|
+
schedule : Fields.Scheduler,
|
|
33
|
+
scheduler : Fields.Scheduler,
|
|
34
|
+
default : Fields.TextField,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function getComponentFromType(type){
|
|
38
|
+
const types = getComponentTypes();
|
|
39
|
+
if(!isNonNullString(type)){
|
|
40
|
+
return types.default;
|
|
41
|
+
}
|
|
42
|
+
type = type.trim().toLowerCase().replaceAll(" ","").replaceAll("-","").replaceAll("_","");
|
|
43
|
+
return React.isComponent(types[type]) && types[type] || types.default;
|
|
35
44
|
};
|
|
36
45
|
|
|
37
|
-
export default
|
|
46
|
+
export default getComponentFromType;
|
|
47
|
+
|
|
38
48
|
|
|
49
|
+
/**** pour interdire qu'on composant FormField soit utilisé en cas de filtre, il suffit de passer au composant FormField, la props filter à false */
|
|
39
50
|
|
|
40
51
|
export const getFilterComponentProps = (_props)=>{
|
|
41
52
|
let {
|
|
@@ -67,6 +78,7 @@ export const getFilterComponentProps = (_props)=>{
|
|
|
67
78
|
...props
|
|
68
79
|
} = _props;
|
|
69
80
|
props = defaultObj(props);
|
|
81
|
+
const componentTypes = getComponentTypes();
|
|
70
82
|
let component = Fields.TextField;
|
|
71
83
|
type = defaultStr(jsType,type,'text').toLowerCase().replaceAll("_","").replaceAll("-","").trim();
|
|
72
84
|
const sanitizedType = type.replaceAll("_","").toLowerCase().trim();
|
|
@@ -101,7 +113,7 @@ export const getFilterComponentProps = (_props)=>{
|
|
|
101
113
|
component = Fields.ColorPicker;
|
|
102
114
|
} else if(type == 'dateformat' || type =='select_dateformat' || type =='select_date_format') {
|
|
103
115
|
component = Fields.SelectDateFormat;
|
|
104
|
-
} else if(React.isComponent(componentTypes[type])) {
|
|
116
|
+
} else if(React.isComponent(componentTypes[type]) && componentTypes[type] !== false) {
|
|
105
117
|
component = componentTypes[type];
|
|
106
118
|
} else if(isNonNullString(props.foreignKeyColumn) && isNonNullString(props.foreignKeyTable)) {
|
|
107
119
|
component = Fields.SelectTableData;
|
|
@@ -112,7 +124,7 @@ export const getFilterComponentProps = (_props)=>{
|
|
|
112
124
|
}
|
|
113
125
|
delete props.dbName;
|
|
114
126
|
delete props.tableName;
|
|
115
|
-
|
|
127
|
+
delete props.fieldName;
|
|
116
128
|
}
|
|
117
129
|
type = type || "text"
|
|
118
130
|
if(type =='select'){
|
|
@@ -91,14 +91,7 @@ export const handleBeforeSaveCallback = (beforeSaveCallback,successCb,arg)=>{
|
|
|
91
91
|
}
|
|
92
92
|
successCb(arg);
|
|
93
93
|
}).catch((e)=>{
|
|
94
|
-
|
|
95
|
-
notify.error(e);
|
|
96
|
-
} else if(e){
|
|
97
|
-
let ms = defaultStr(e.msg,e.message);
|
|
98
|
-
if(isNonNullString(ms)){
|
|
99
|
-
notify.error(ms);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
94
|
+
notify.error(e);
|
|
102
95
|
})
|
|
103
96
|
return arg;
|
|
104
97
|
} else if(isNonNullString(bF)){
|
|
@@ -36,7 +36,6 @@ const IconButtonComponent = ({
|
|
|
36
36
|
const borderColor = theme.colors.outline || theme.colors.divider;
|
|
37
37
|
const rippleColor = Colors.setAlpha(iconColor,0.32);
|
|
38
38
|
const buttonSize = size * 1.5;
|
|
39
|
-
console.log(iconColor, " is conndddd ",color,rest);
|
|
40
39
|
const borderStyles = {
|
|
41
40
|
borderWidth: 0,
|
|
42
41
|
borderRadius: buttonSize / 2,
|
|
@@ -41,7 +41,7 @@ const TableLinKComponent = React.forwardRef((props,ref)=>{
|
|
|
41
41
|
const r2 = typeof fetchForeignData === 'function'? fetchForeignData({...args,...defaultObj(a)}) : undefined;
|
|
42
42
|
if(isPromise(r2)){
|
|
43
43
|
return r2.then((data)=>{
|
|
44
|
-
if(isObj(data) && data[foreignKeyColumn] !== undefined){
|
|
44
|
+
if(isObj(data) && (isNonNullString(foreignKeyColumn) ? data[foreignKeyColumn] !== undefined:true)){
|
|
45
45
|
navigateToTableData({tableName:foreignKeyTable,data});
|
|
46
46
|
}
|
|
47
47
|
});
|
|
@@ -81,7 +81,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
81
81
|
const f = fields[i];
|
|
82
82
|
f.type = defaultStr(f.jsType,f.type).toLowerCase();
|
|
83
83
|
const name = f.field = defaultStr(f.field,i);
|
|
84
|
-
if((f.type =='id' || f.type =='piece' || f.unique === true) && f.unique !== false && f.disabled !== true && f.editable !== false && f.readOnly !== true){
|
|
84
|
+
if((f.type =='id' || f.type =='piece' || f.primaryKey || f.unique === true) && f.unique !== false && f.disabled !== true && f.editable !== false && f.readOnly !== true){
|
|
85
85
|
const {onBlur} = f;
|
|
86
86
|
f.onBlur = (args)=>{
|
|
87
87
|
args = {...f,...args,fetch,columnField:name,fieldName:name,id:args.value};
|
|
@@ -104,6 +104,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
104
104
|
}
|
|
105
105
|
}).catch((e)=>{
|
|
106
106
|
if(e && e.status?.toString() == '404') return;
|
|
107
|
+
console.log(e," fetching unique id on table data element id : ",args)
|
|
107
108
|
const message = defaultStr(e?.message,e?.msg);
|
|
108
109
|
if(message){
|
|
109
110
|
context.onNoValidate({...args,msg:message,message,error:e,context,validRule:context.getValidRule()});
|