@fto-consult/expo-ui 8.71.0 → 8.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/bin/create-app/dependencies.js +3 -3
  2. package/package.json +4 -4
  3. package/src/components/BottomSheet/Sheet.js +1 -1
  4. package/src/components/Button/Status.js +10 -1
  5. package/src/components/Datagrid/Accordion/index.js +1 -1
  6. package/src/components/Dialog/Dialog.js +5 -2
  7. package/src/components/DocumentPicker/index.js +111 -7
  8. package/src/components/Dropdown/index.js +35 -23
  9. package/src/components/Form/Fields/DocumentPicker.js +63 -0
  10. package/src/components/Form/Fields/Field.js +4 -6
  11. package/src/components/Form/Fields/Image.js +3 -22
  12. package/src/components/Form/Fields/SelectField.js +1 -1
  13. package/src/components/Form/Fields/SelectTableData/Component.js +23 -6
  14. package/src/components/Form/Fields/index.js +3 -1
  15. package/src/components/Form/FormData/componentsTypes.js +1 -0
  16. package/src/components/Form/utils/FormsManager.js +11 -5
  17. package/src/components/List/hooks.js +2 -2
  18. package/src/components/Menu/Menu.js +5 -3
  19. package/src/components/TableLink/index.js +8 -3
  20. package/src/layouts/Screen/TableData.js +1 -2
  21. package/src/media/Assets/utils.js +9 -2
  22. package/src/screens/Help/openLibraries.js +81 -124
  23. package/src/table-data/importer/parser.js +1824 -0
  24. package/src/{importer → table-data/importer}/run.js +0 -1
  25. /package/src/{importer → table-data/importer}/getSelectFieldValue.js +0 -0
  26. /package/src/{importer → table-data/importer}/index.js +0 -0
  27. /package/src/{importer → table-data/importer}/parseCSV.js +0 -0
  28. /package/src/{importer → table-data/importer}/validate.js +0 -0
@@ -11,8 +11,8 @@
11
11
  "@react-navigation/native-stack": "^6.9.26",
12
12
  "@react-navigation/stack": "^6.3.29",
13
13
  "@shopify/flash-list": "1.6.3",
14
- "expo": "^50.0.15",
15
- "expo-camera": "~14.1.2",
14
+ "expo": "^50.0.17",
15
+ "expo-camera": "~14.1.3",
16
16
  "expo-clipboard": "~5.0.1",
17
17
  "expo-font": "~11.10.3",
18
18
  "expo-image-picker": "~14.7.1",
@@ -20,7 +20,7 @@
20
20
  "expo-sharing": "~11.10.0",
21
21
  "expo-sqlite": "~13.4.0",
22
22
  "expo-status-bar": "~1.11.1",
23
- "expo-system-ui": "~2.9.3",
23
+ "expo-system-ui": "~2.9.4",
24
24
  "expo-web-browser": "~12.8.2",
25
25
  "react": "18.2.0",
26
26
  "react-native": "0.73.6",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fto-consult/expo-ui",
3
- "version": "8.71.0",
3
+ "version": "8.73.0",
4
4
  "description": "Bibliothèque de composants UI Expo,react-native",
5
5
  "react-native-paper-doc": "https://github.com/callstack/react-native-paper/tree/main/docs/docs/guides",
6
6
  "scripts": {
@@ -70,7 +70,7 @@
70
70
  "dependencies": {
71
71
  "@emotion/react": "^11.11.1",
72
72
  "@faker-js/faker": "^8.0.2",
73
- "@fto-consult/common": "^4.41.1",
73
+ "@fto-consult/common": "^4.44.3",
74
74
  "apexcharts": "^3.48.0",
75
75
  "file-saver": "^2.0.5",
76
76
  "google-libphonenumber": "^3.2.34",
@@ -85,9 +85,9 @@
85
85
  "react-native-iphone-x-helper": "^1.3.1",
86
86
  "react-native-mime-types": "^2.5.0",
87
87
  "react-native-paper": "^5.12.3",
88
- "react-native-paper-dates": "^0.22.6",
88
+ "react-native-paper-dates": "^0.22.7",
89
89
  "react-native-web": "^0.19.10",
90
- "react-virtuoso": "^4.7.8",
90
+ "react-virtuoso": "^4.7.9",
91
91
  "readable-stream": "^4.5.2",
92
92
  "sanitize-filename": "^1.6.3",
93
93
  "tippy.js": "^6.3.7",
@@ -228,7 +228,7 @@ const BottomSheetComponent = React.forwardRef((props,ref)=> {
228
228
 
229
229
  React.setRef(ref,{close:closeModal,open})
230
230
  React.useEffect(()=>{
231
- if(bindResizeEvent){
231
+ if(bindResizeEvent && false){
232
232
  APP.on(APP.EVENTS.RESIZE_PAGE,closeModal);
233
233
  }
234
234
  return ()=>{
@@ -28,7 +28,7 @@ const ButtonStatusComponent = React.forwardRef(({status,withIcon,color,backgroun
28
28
  left = typeof left =='function'? left(rP) : left;
29
29
  right = typeof right =='function'? right(rP) : right;
30
30
  const icProps = {color,size:15,...iconProps,style:[theme.styles.noMargin,theme.styles.noPadding,iconProps.style],onPress}
31
- return <Pressable ref={ref} onPres={onPress} testID={`${testID}_Container`} {...containerProps} style={[{borderRadius:15,paddingVertical:4,paddingHorizontal:10,alignSelf: 'flex-start'},theme.styles.row,theme.styles.flexWrap,backgroundColor && {backgroundColor},style]}>
31
+ return <Pressable ref={ref} onPres={onPress} testID={`${testID}_Container`} {...containerProps} style={[styles.button,theme.styles.row,theme.styles.flexWrap,backgroundColor && {backgroundColor},style]}>
32
32
  {React.isValidElement(left)? left : null}
33
33
  {withIcon !== false && React.isValidElement(icon,true) ? <Icon {...icProps} icon={icon} />:null}
34
34
  {label ? <Label testID={`${testID}_Label`} {...labelProps} style={[color && {color},{fontSize:13},labelProps.style]}>{label}</Label> : null}
@@ -46,6 +46,15 @@ ButtonStatusComponent.defaultProps = {
46
46
  editable : false,
47
47
  }
48
48
 
49
+ const styles = StyleSheet.create({
50
+ button : {
51
+ borderRadius:15,
52
+ paddingVertical:4,
53
+ paddingHorizontal:10,
54
+ alignSelf: 'flex-start',
55
+ }
56
+ });
57
+
49
58
  ButtonStatusComponent.propTypes = {
50
59
  label : PropTypes.oneOfType([ //le libelé à faire figurer sur le status
51
60
  PropTypes.node,
@@ -552,7 +552,7 @@ const DatagridFactory = (Factory)=>{
552
552
  extraData = {this.state.refresh}
553
553
  contentInset={{ right: 10, top: 10, left: 10, bottom: 10 }}
554
554
  itemHeight = {undefined}
555
- responsive = {defaultBool(responsive,rest.responsive,accordionProps.responsive,true)}
555
+ responsive = {defaultBool(this.hasSectionListData()? false : undefined,responsive,rest.responsive,accordionProps.responsive,true)}
556
556
  filter = {filter}
557
557
  getItemType = {this.getFlashListItemType.bind(this)}
558
558
  renderItem = {this.renderItem.bind(this)}
@@ -177,8 +177,11 @@ const DialogComponent = React.forwardRef((props,ref)=>{
177
177
  containerProps.mediaQueryUpdateStyle = (...rest)=>{
178
178
  const r = typeof mediaQueryUpdateStyle =="function"? mediaQueryUpdateStyle(...rest) : undefined;
179
179
  const {width,height} = rest[0];
180
- const rW = setDimensions !== false ? {width,height} : {};
181
- return isFullScreenDialog()? [r,{...rW,maxWidth:"100%",maxHeight:"100%"}] : [r,setDimensions !== false && {maxHeight:getMaxHeight(),maxWidth:getMaxWidth()}];
180
+ let rW = setDimensions !== false ? {width,height} : {};
181
+ if(setDimensions !== false && isFullScreenDialog()){
182
+ rW = {width:'100%',height:'100%',minHeight:height,maxWidth:"100%",maxHeight:"100%"};
183
+ }
184
+ return isFullScreenDialog()? [r,rW] : [r,setDimensions !== false && {maxHeight:getMaxHeight(),maxWidth:getMaxWidth()}];
182
185
  }
183
186
  }
184
187
  return containerProps;
@@ -2,31 +2,135 @@ import Button from "$ecomponents/Button";
2
2
  import React from "$react";
3
3
  import PropTypes from "prop-types";
4
4
  import { pickDocument } from "$emedia/document";
5
+ import { StyleSheet } from "react-native";
6
+ import {isObj,isNonNullString,extendObj,defaultObj,defaultBool} from "$cutils";
7
+ import Label from "$ecomponents/Label";
8
+ import theme from "$theme";
5
9
 
6
- const DocumentPickerComponent = React.forwardRef(({pickOptions,onSuccess,onCancel,onPress,...props},ref)=>{
7
- return <Button
10
+
11
+ const DocumentPickerComponent = React.forwardRef(({pickOptions,label,error,left,errorText,labelProps,containerProps,text:cText,onChange,onCancel,style,onPress,...props},ref)=>{
12
+ const [assets,setAssets] = React.useState([]);
13
+ label = React.isValidElement(label,true) && label || React.isValidElement(cText,true) && cText || null;
14
+ const changedRef = React.useRef(null);
15
+ labelProps = defaultObj(labelProps);
16
+ containerProps = defaultObj(containerProps);
17
+ const multiple = defaultBool(pickOptions?.multiple,props.multiple);
18
+ const {text,tooltip} = React.useMemo(()=>{
19
+ let text = ``,tooltip = "";
20
+ let counter = 0;
21
+ let breakCounter = 0;
22
+ (Array.isArray(assets) ?assets:[assets]).map((a)=>{
23
+ if(!isObj(a) || !isNonNullString(a.name)) return;
24
+ tooltip+=`${tooltip?",":""}${a.name}`
25
+ if(counter < 1){
26
+ text+=`${text?",":""}${a.name}`
27
+ } else {
28
+ breakCounter++;
29
+ }
30
+ counter++;
31
+ });
32
+ return {
33
+ text : text+(breakCounter> 0?` et ${breakCounter.formatNumber()} de plus`:""),
34
+ tooltip,
35
+ }
36
+ },[assets]);
37
+ React.useEffect(()=>{
38
+ if(!isObj(changedRef.current)) return;
39
+ const args = changedRef.current;
40
+ changedRef.current = null;
41
+ if(typeof onChange =="function"){
42
+ onChange({...args,value:assets});
43
+ }
44
+ },[assets]);
45
+ const textColor = error? theme.colors.error : theme.colors.text;
46
+ const textFieldMode = theme.textFieldMode;
47
+ const borderColor = theme.colors[error?"error":"divider"];
48
+ const isFlatMode = textFieldMode == "flat";
49
+ const containerStyle = isFlatMode ? {} : {paddingHorizontal : 10}
50
+ const labelColor = error ? theme.colors.error : theme.Colors.setAlpha(theme.colors.text,theme.ALPHA);
51
+ const rStyle = isFlatMode ? {borderWidth:0,borderBottomWidth:1,borderBottomColor:borderColor} : {
52
+ borderWidth : 1,
53
+ borderRadius:15,
54
+ borderColor,
55
+ };
56
+ const btn = <Button
8
57
  onPress = {(...r)=>{
9
58
  if(typeof onPress =="function" && onPress(...r) === false) return;
10
- pickDocument(pickOptions).then((r)=>{
11
- if(typeof onSuccess =="function"){
12
- onSuccess(r);
59
+ pickDocument(extendObj({},pickOptions,{multiple})).then((r)=>{
60
+ r.assets = Array.isArray(r.assets)? r.assets : [];
61
+ if(!multiple){
62
+ r.assets = r.assets[0];
13
63
  }
64
+ changedRef.current = r;
65
+ setAssets(r.assets);
14
66
  }).catch((r)=>{
15
67
  if(typeof onCancel =="function"){
16
68
  onCancel(r);
17
69
  }
18
70
  });
19
71
  }}
20
- ref={ref} {...props}/>
72
+ left = {(props)=>{
73
+ const c = typeof left =="function"? left(props) : React.isValidElement(left)? left : null;
74
+ const lL = <Label children={`Choisir ${multiple ? "des fichiers":"un fichier" }`} style={[styles.leftLabel,{color:textColor,borderRightColor:theme.colors.divider}]}/>;
75
+ return React.isValidElement(c)? <>
76
+ {c}{lL}
77
+ </> : lL;
78
+ }}
79
+ style = {[styles.button,style]}
80
+ upperCase ={false}
81
+ ref={ref} {...props}
82
+ children = {text || "Aucun fichier choisit"}
83
+ tooltip = {tooltip}
84
+ title = {tooltip}
85
+ labelProps = {{style:styles.label,splitText:true,numberOfLines : 1,color:textColor}}
86
+ containerProps = {{...containerProps,style:[styles.container,containerStyle,rStyle,containerProps.style]}}
87
+ />;
88
+ return <>
89
+ {label?<Label {...labelProps} style={[{color:labelColor},labelProps.style]} children={label}/> : null}
90
+ {btn}
91
+ {errorText? <Label error children={errorText}/>:null}
92
+ </>
21
93
  });
22
94
 
23
95
  DocumentPickerComponent.displayName = "DocumentPickerComponent";
24
96
 
25
97
  export default DocumentPickerComponent;
26
98
 
99
+ const styles = StyleSheet.create({
100
+ button : {
101
+ alignSelf: 'flex-start',
102
+ },
103
+ leftLabel : {
104
+ paddingVertical : 12,
105
+ borderRightWidth : 1,
106
+ textWrap : "nowrap",
107
+ paddingRight : 7,
108
+ },
109
+ label : {
110
+ paddingHorizontal : 5,
111
+ textWrap : "wrap",
112
+ textAlign : "left",
113
+ },
114
+ container : {
115
+ marginTop : 5,
116
+ }
117
+ });
118
+
27
119
  DocumentPickerComponent.propTypes = {
120
+ label : PropTypes.oneOfType([
121
+ PropTypes.node,
122
+ PropTypes.element,
123
+ PropTypes.string,
124
+ PropTypes.number,
125
+ ]),
126
+ text : PropTypes.oneOfType([
127
+ PropTypes.node,
128
+ PropTypes.element,
129
+ PropTypes.string,
130
+ PropTypes.number,
131
+ ]),
28
132
  ...Object.assign({},Button.propTypes),
29
- onSuccess : PropTypes.func,
133
+ onChange : PropTypes.func,
30
134
  onCancel : PropTypes.func,
31
135
  /*** @see : https://docs.expo.dev/versions/latest/sdk/document-picker/#documentpickeroptions */
32
136
  pickOptions : PropTypes.shape({
@@ -35,6 +35,11 @@ const MAX_SELECTED_ITEMS = 2;
35
35
 
36
36
  export const isValidValueKey = valueKey => isNonNullString(valueKey);
37
37
 
38
+ /***
39
+ au cas où les données sont chargées depuis la bd,
40
+ la props isLoading doit être passée à true à ce compossant
41
+ elle devra être remise à false une fois le chargement des données terminé
42
+ */
38
43
  class DropdownComponent extends AppComponent {
39
44
  constructor(props){
40
45
  super(props);
@@ -106,7 +111,7 @@ class DropdownComponent extends AppComponent {
106
111
  return index;
107
112
  }, override : false, writable : false
108
113
  },
109
- canHandleMultiple : {
114
+ isDefaultMultiplePropEnabled : {
110
115
  value : !!multiple,
111
116
  override : false, writable : false,
112
117
  },
@@ -120,6 +125,7 @@ class DropdownComponent extends AppComponent {
120
125
 
121
126
  extendObj(this.state,{
122
127
  initialized : false,
128
+ selected : this.prepareSelected({defaultValue}),
123
129
  filterText : "",
124
130
  anchorHeight : undefined,
125
131
  isMobileMedia : isMobileOrTabletMedia(),
@@ -134,6 +140,9 @@ class DropdownComponent extends AppComponent {
134
140
  this.inputRef = React.createRef(null);
135
141
  this.listRef = React.createRef(null);
136
142
  }
143
+ canHandleMultiple (){
144
+ return !!this.props.multiple;
145
+ }
137
146
  updateSelected (nState,force){
138
147
  nState = defaultObj(nState);
139
148
  //this.countEee = defaultNumber(this.countEee)+1;
@@ -148,7 +157,7 @@ class DropdownComponent extends AppComponent {
148
157
  let selectedItem = null;
149
158
  const valueKey = this.getValueKey(this.state.selected);
150
159
  if(this.state.initialized && !force){
151
- if(!this.canHandleMultiple){
160
+ if(!this.canHandleMultiple()){
152
161
  if(valueKey && this.state.valuesKeys[valueKey]){
153
162
  selectedItem = this.state.valuesKeys[valueKey].item;
154
163
  }
@@ -185,9 +194,9 @@ class DropdownComponent extends AppComponent {
185
194
  },force);
186
195
  }
187
196
  selectItem ({value,select,valueKey}){
188
- let selected = this.canHandleMultiple ? [...this.state.selected] : undefined;
197
+ let selected = this.canHandleMultiple() ? [...this.state.selected] : undefined;
189
198
  let selectedValuesKeys = {...this.state.selectedValuesKeys};
190
- if(this.canHandleMultiple){
199
+ if(this.canHandleMultiple()){
191
200
  if(!select){
192
201
  if(valueKey in selectedValuesKeys){
193
202
  const newS = [];
@@ -215,7 +224,7 @@ class DropdownComponent extends AppComponent {
215
224
  }
216
225
  this.willHandleFilter = false;
217
226
  let nState = {};
218
- if(!this.canHandleMultiple){
227
+ if(!this.canHandleMultiple()){
219
228
  nState.visible = false;
220
229
  }
221
230
  this.updateSelected({...nState,data:!this.isBigList?[...this.state.data]: this.state.data,selected,selectedValuesKeys});
@@ -234,7 +243,7 @@ class DropdownComponent extends AppComponent {
234
243
  if(valueKey && forceCheck !== true){
235
244
  return valueKey in this.state.selectedValuesKeys ? true : false;
236
245
  }
237
- if(this.canHandleMultiple) {
246
+ if(this.canHandleMultiple()) {
238
247
  currentSelected = Array.isArray(currentSelected)? currentSelected : this.state.selected;
239
248
  for(let i in currentSelected){
240
249
  if(this.compare(currentValue,currentSelected[i])) return true;
@@ -246,7 +255,7 @@ class DropdownComponent extends AppComponent {
246
255
  }
247
256
  prepareSelected({defaultValue}){
248
257
  let s = defaultValue !== undefined ? defaultValue : undefined;
249
- if(this.canHandleMultiple){
258
+ if(this.canHandleMultiple()){
250
259
  if(isNonNullString(s)){
251
260
  s = s.split(",");//si c'est un tableau, ça doit être séparé de virgule
252
261
  } else {
@@ -291,7 +300,7 @@ class DropdownComponent extends AppComponent {
291
300
  if(isObj(valuesKeys[valueKey])){
292
301
  const node = valuesKeys[valueKey];
293
302
  const text = node.text;
294
- if(!this.canHandleMultiple){
303
+ if(!this.canHandleMultiple()){
295
304
  sDText = text;
296
305
  } else {
297
306
  counter++;
@@ -306,7 +315,7 @@ class DropdownComponent extends AppComponent {
306
315
  for(let i in selectedValues){
307
316
  const text = selectedValues[i];
308
317
  if(!isNonNullString(text) && typeof text !=="number") continue;
309
- if(!this.canHandleMultiple){
318
+ if(!this.canHandleMultiple()){
310
319
  sDText = String(text);
311
320
  } else {
312
321
  counter++;
@@ -322,13 +331,13 @@ class DropdownComponent extends AppComponent {
322
331
  } else {
323
332
  this.toggleHasNoValidSelectedValue(false);
324
333
  }
325
- if(this.canHandleMultiple && counter > maxCount && sDText){
334
+ if(this.canHandleMultiple() && counter > maxCount && sDText){
326
335
  sDText+= ", et "+((counter-maxCount).formatNumber()+" de plus")
327
336
  }
328
337
  return sDText;
329
338
  }
330
339
  pushSelectedValue(value,selectedStateValue){
331
- if(this.canHandleMultiple){
340
+ if(this.canHandleMultiple()){
332
341
  selectedStateValue = Array.isArray(selectedStateValue)?selectedStateValue : [];
333
342
  selectedStateValue.push(value);
334
343
  return selectedStateValue;
@@ -349,7 +358,7 @@ class DropdownComponent extends AppComponent {
349
358
  const valuesKeys = {};
350
359
  const {filter} = this.props;
351
360
  const currentSelected = this.prepareSelected({defaultValue:this.props.defaultValue,...args});
352
- let selected = this.canHandleMultiple ? []:undefined,selectedValuesKeys={};
361
+ let selected = this.canHandleMultiple() ? []:undefined,selectedValuesKeys={};
353
362
  const itemProps = defaultObj(this.props.itemProps);
354
363
  const itemsData = this.getItemsData(args);
355
364
  Object.map(itemsData,(item,index,_index)=>{
@@ -402,12 +411,12 @@ class DropdownComponent extends AppComponent {
402
411
  let hasChanged = false;
403
412
  selectOnlyOne = selectOnlyOne === true ? true : false;
404
413
  let newSelected = undefined;
405
- if(this.canHandleMultiple){
414
+ if(this.canHandleMultiple()){
406
415
  newSelected = selectOnlyOne ? [] : [...this.state.selected];
407
416
  }
408
417
  const selectedValuesKeys = selectOnlyOne?{}:{...this.state.selectedValuesKeys};
409
418
  const sVal = this.prepareSelected({defaultValue:value});
410
- if(this.canHandleMultiple){
419
+ if(this.canHandleMultiple()){
411
420
  if(sVal.length !== this.state.selected.length){
412
421
  hasChanged = true;
413
422
  }
@@ -436,7 +445,7 @@ class DropdownComponent extends AppComponent {
436
445
  }
437
446
 
438
447
  selectAll (){
439
- if(!this.canHandleMultiple) return;
448
+ if(!this.canHandleMultiple()) return;
440
449
  const newSelected = [],selectedValuesKeys={};
441
450
  this.state.data.map((item,_index)=>{
442
451
  const key = this.keysRefs[_index];
@@ -447,11 +456,11 @@ class DropdownComponent extends AppComponent {
447
456
  this.updateSelected({selected:newSelected,selectedValuesKeys,selectedText:this.getSelectedText(newSelected,selectedValuesKeys)});
448
457
  }
449
458
  unselectAll() {
450
- if(!this.canHandleMultiple) return;
459
+ if(!this.canHandleMultiple()) return;
451
460
  this.updateSelected({selected:[],selectedValuesKeys:{},selectedText:''})
452
461
  }
453
462
  unselect (oState){
454
- this.updateSelected({...defaultObj(oState),selected:this.canHandleMultiple ?[]:undefined,selectedValuesKeys:{},selectedText:""});
463
+ this.updateSelected({...defaultObj(oState),selected:this.canHandleMultiple() ?[]:undefined,selectedValuesKeys:{},selectedText:""});
455
464
  }
456
465
  getSelectedValue (){
457
466
  return this.getSelected();
@@ -461,7 +470,7 @@ class DropdownComponent extends AppComponent {
461
470
  }
462
471
  getSelectedItems (){
463
472
  let ret = {};
464
- if(this.canHandleMultiple){
473
+ if(this.canHandleMultiple()){
465
474
  Object.map(this.state.selected,(value)=>{
466
475
  const nodeKey = this.getNodeFromValue(value);
467
476
  if(!nodeKey.valueKey) return;
@@ -654,15 +663,18 @@ class DropdownComponent extends AppComponent {
654
663
  UNSAFE_componentWillReceiveProps(nextProps){
655
664
  const {items,defaultValue,selected} = nextProps;
656
665
  const isFunc = typeof nextProps.items == "function";
666
+ if(nextProps.isLoading === true) return;
657
667
  if(isFunc || !React.areEquals(items,this.props.items)){
658
668
  const nState = this.prepareItems({items,defaultValue,selected});
659
669
  return this.updateSelected(nState,!isFunc);
660
670
  }
661
671
  let value = this.prepareSelected({defaultValue});
662
- let areEquals = !this.canHandleMultiple ? this.compare(value,this.state.selected) : false;
663
- if(areEquals) return;
664
- let selectedValuesKeys = {}, newSelected = this.canHandleMultiple ? [] : value;
665
- if(this.canHandleMultiple){
672
+ let areEquals = !this.canHandleMultiple() ? this.compare(value,this.state.selected) : false;
673
+ if(areEquals) {
674
+ return;
675
+ }
676
+ let selectedValuesKeys = {}, newSelected = this.canHandleMultiple() ? [] : value;
677
+ if(this.canHandleMultiple()){
666
678
  areEquals = value.length === this.state.selected.length;
667
679
  if(areEquals && !value.length){
668
680
  areEquals = true;
@@ -771,7 +783,7 @@ class DropdownComponent extends AppComponent {
771
783
  const flattenStyle = StyleSheet.flatten(dropdownProps.style) || {};
772
784
  itemContainerProps = defaultObj(itemContainerProps);
773
785
  dropdownProps = defaultObj(dropdownProps);
774
- const multiple = this.canHandleMultiple;
786
+ const multiple = this.canHandleMultiple();
775
787
  const renderTag = multiple && (display == 'tags' || display === 'tag' )? true : false;
776
788
  this.willRenderTag = renderTag;
777
789
 
@@ -0,0 +1,63 @@
1
+ import Field from "./Field";
2
+ import DocumentPicker from "$ecomponents/DocumentPicker";
3
+ import {isObj,defaultObj} from "$cutils";
4
+ export default class FormFieldDocumentPicker extends Field {
5
+ canFocus(){
6
+ return false;
7
+ }
8
+ isValid(){
9
+ return true;
10
+ }
11
+ compareAssets(assets){
12
+ if(Array.isArray(assets)){
13
+ const previousValue = this.getPreviousValue();
14
+ const allPrev = Array.isArray(previousValue)? previousValue : [previousValue];
15
+ for(let i in assets){
16
+ let hasFound = false;
17
+ for(let j in allPrev){
18
+ if(this.compareSingleAssets(assets[i],allPrev[j])) {
19
+ hasFound = true;
20
+ }
21
+ if(hasFound) break;
22
+ }
23
+ if(!hasFound) return false;
24
+ }
25
+ return true;
26
+ }
27
+ return this.compareSingleAssets(assets,this.getPreviousValue());
28
+ }
29
+ compareSingleAssets(assets,previousValue){
30
+ if(!isObj(assets) || !isObj(previousValue)) return false;
31
+ return previousValue.lastModified === assets.lastModified && previousValue.mimeType == assets.mimeType && previousValue.name === assets.name && previousValue.size == assets.size && previousValue.uri == assets.uri;
32
+ }
33
+ onChange(args){
34
+ const assets = Array.isArray(args.assets) ? args.assets : [args.assets];
35
+ const value = this.props.multiple ? assets:assets[0];
36
+ if(this.compareAssets(value)){
37
+ return ;
38
+ }
39
+ this.validate({...args,value,context:this});
40
+ }
41
+ getComponent(){
42
+ return DocumentPicker;
43
+ }
44
+ _render({pickOptions,...props}){
45
+ pickOptions = defaultObj(pickOptions,props);
46
+ if(typeof this.props.multiple =="boolean"){
47
+ pickOptions.multiple = this.props.multiple;
48
+ }
49
+ return <DocumentPicker
50
+ {...props}
51
+ pickOptions = {pickOptions}
52
+ onChange = {this.onChange.bind(this)}
53
+ />
54
+ }
55
+ isTextField(){
56
+ return false;
57
+ }
58
+ }
59
+
60
+ FormFieldDocumentPicker.propTypes = {
61
+ ...Field.propTypes,
62
+ ...DocumentPicker.propTypes,
63
+ }
@@ -251,8 +251,7 @@ export default class Field extends AppComponent {
251
251
  }
252
252
  this.validatingValue = value;
253
253
  this.INITIAL_STATE._lastValidatingValue = value;
254
- this.setState ({validValue:value,validatingValue:value,previousValue:this.state.validValue,errorText:"",error:false},()=>{
255
- this._previousValue = this.state.validValue;
254
+ this.setState ({validValue:value,previousValidatedValue:this.state.validValue,validatingValue:value,previousValue:this.state.validValue,errorText:"",error:false},()=>{
256
255
  const fields = getFormFields(this.formName);
257
256
  let canEnable = true;
258
257
  for(var k in fields){
@@ -405,7 +404,7 @@ export default class Field extends AppComponent {
405
404
  return this.formName;
406
405
  }
407
406
  getOldValue () {
408
- return this._previousValue;
407
+ return this.state.previousValidatedValue;
409
408
  }
410
409
  /*** la valeur qui a été validée
411
410
  * @param : l'ensemble des données du formulaire à retourner
@@ -517,7 +516,7 @@ export default class Field extends AppComponent {
517
516
  return false;
518
517
  }
519
518
  getPreviousValue (){
520
- return this._previousValue;
519
+ return this.state.previousValidatedValue;
521
520
  }
522
521
  hasValueChanged(value){
523
522
  return (stableHash(this.state.validatingValue) === stableHash(value))? false : true;
@@ -541,9 +540,8 @@ export default class Field extends AppComponent {
541
540
  this.__hasAlreadyValidated = true;
542
541
  this.validatingValue = value;
543
542
  if(((!this.canValidate()) && !this.isSelectField()) || this.isFilter()){
544
- this._previousValue = this.state.validValue;
545
543
  this.trigger("validate",{...defaultObj(rest),context:this,value,event,oldValue:this.INITIAL_STATE._lastValidatingValue},(results)=>{
546
- this.setState({validValue:value,validatingValue:value,sk:!this.state.sk,previousValue:this.state.validatingValue},()=>{
544
+ this.setState({validValue:value,previousValidatedValue:this.state.validValue,validatingValue:value,sk:!this.state.sk,previousValue:this.state.validatingValue},()=>{
547
545
  if(isFunction(this.props.onValidate)){
548
546
  this.props.onValidate({...defaultObj(rest),props:this.props,name:this.name,field:this.name,value,event,context:this,oldValue:this.INITIAL_STATE._lastValidatingValue});
549
547
  }
@@ -23,19 +23,15 @@ export default class FormFieldImage extends Field {
23
23
  return ;
24
24
  }
25
25
  this.validate({...args,value:dataUrl,context:this});
26
- /*if(isFunction(this.props.onChange)){
27
- this.props.onChange({dataUrl,src:dataUrl,dataURL:dataUrl,previousSrc:previousValue});
28
- }*/
29
26
  }
30
27
  getComponent(){
31
28
  return Image;
32
29
  }
33
- _render(props){
34
- let {dbName,onChange,...p} = props;
35
- p.onChange = this.onChange.bind(this);
30
+ _render({onChange,...p}){
36
31
  return <Image
37
32
  {...p}
38
33
  src={defaultVal(p.src,p.defaultValue)}
34
+ onChange={this.onChange.bind(this)}
39
35
  />
40
36
  }
41
37
  isTextField(){
@@ -46,20 +42,5 @@ export default class FormFieldImage extends Field {
46
42
  FormFieldImage.propTypes = {
47
43
  width : PropTypes.number,
48
44
  height : PropTypes.number,
49
- /*** le nom du champ qu'on valide
50
- * si fieldName est définie, alors, il est utilisé pour la validation du champ.
51
- * lorsque la valeur est mise à jour, on recherche en base toutes les objets ayant pour valeur ladite valeur
52
- * Si est trouvé, alors une erreur est retournée.
53
- * Dans le cas où fieldName est définie, alors, l'id n'est pas utilisé pour la validation
54
- *
55
- */
56
- fieldName : PropTypes.string,
57
- ...Field.propTypes,
58
- /*** le nom de la table dans laquelle l'idField est enreigistré */
59
- table : PropTypes.string,
60
- tableName : PropTypes.string, //idem à table
61
- /*** le nom de la bd où l'id field est enregistré */
62
- dbName : PropTypes.string,
63
- //la longueur maximale du champ
64
- maxLength:PropTypes.number
45
+ ...Field.propTypes
65
46
  }
@@ -108,7 +108,7 @@ export default class FormSelectField extends Field{
108
108
  args.selectedItems = this._field.getSelectedItems();
109
109
  }
110
110
  args.value = this._field.prepareSelected({defaultValue:args.value})
111
- if(!this._field.canHandleMultiple && !args.selectedItem){
111
+ if(!(typeof this._field.canHandleMultiple =='function' && this._field.canHandleMultiple()) && !args.selectedItem){
112
112
  const valueKey = this._field.getValueKey(args.value);
113
113
  if(valueKey && isObj(this._field.state.valuesKeys) && this._field.state.valuesKeys[valueKey]){
114
114
  args.selectedItem = args.item = this._field.state.valuesKeys[valueKey].item;