@fto-consult/expo-ui 2.11.4 → 2.12.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.
@@ -38,6 +38,10 @@ module.exports = (opts)=>{
38
38
  r["$expo"] = r["$expo-ui"] = expo;
39
39
  r["$epreloader"] = path.resolve(expo,"components/Preloader");
40
40
  r["$eform"] = path.resolve(expo,"components","Form");
41
+
42
+ //l'alias $extendFormFields, pour étendre les formFields qu'on veut définir
43
+ r["$extendFormFields"] = r["$extendFormFields"] || path.resolve(r["$eform"],"Fields","$extendFormFields")
44
+
41
45
  r["$form"] = r["$form"] || r["$eform"];
42
46
  r["$eform-data"] = r["$eformData"]= path.resolve(expo,"components","Form","FormData");
43
47
  r["$formData"] = r["$formData"] || r["$eformData"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fto-consult/expo-ui",
3
- "version": "2.11.4",
3
+ "version": "2.12.0",
4
4
  "description": "Bibliothèque de composants UI Expo,react-native",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -65,7 +65,7 @@
65
65
  "@expo/metro-config": "^0.4.0",
66
66
  "@expo/vector-icons": "^13.0.0",
67
67
  "@expo/webpack-config": "^0.17.2",
68
- "@fto-consult/common": "^1.20.0",
68
+ "@fto-consult/common": "^1.20.1",
69
69
  "@gorhom/portal": "^1.0.14",
70
70
  "@react-native-async-storage/async-storage": "~1.17.3",
71
71
  "@react-native-community/datetimepicker": "6.5.2",
@@ -21,6 +21,7 @@ export const getCountryFieldProps = (props)=>{
21
21
  upper : true,
22
22
  dialogProps : {title:'Sélectionner un pays'},
23
23
  getItemValue : ({item})=>item.code,
24
+ renderText : ({item})=>"[{0}] {1}".sprintf(item?.code?.toUpperCase(),item?.label),
24
25
  compare : (a,b)=>{
25
26
  return typeof a ==='string' && typeof b =='string' && a.toLowerCase() === b.toLowerCase() ? true : false;
26
27
  },
@@ -19,7 +19,7 @@ import React from "$react";
19
19
  import DateLib from "$lib/date";
20
20
  import Filter,{canHandleFilter,prepareFilters} from "$ecomponents/Filter";
21
21
  import {CHECKED_ICON_NAME} from "$ecomponents/Checkbox";
22
- import { COLUMN_WIDTH,DATE_COLUMN_WIDTH } from "../utils";
22
+ import { COLUMN_WIDTH,DATE_COLUMN_WIDTH,willConvertFiltersToSQL } from "../utils";
23
23
  import { StyleSheet,Dimensions,useWindowDimensions} from "react-native";
24
24
  import Preloader from "$ecomponents/Preloader";
25
25
  import Checkbox from "../Checkbox";
@@ -1262,7 +1262,7 @@ export default class CommonDatagridComponent extends AppComponent {
1262
1262
  }
1263
1263
  ///si les filtres devront être convertis au format SQL
1264
1264
  willConvertFiltersToSQL(){
1265
- return !!defaultVal(this.props.convertFiltersToSQL,appConfig.get("convertDatagridFiltersToSQL"));;
1265
+ return !!defaultVal(this.props.convertFiltersToSQL,willConvertFiltersToSQL());;
1266
1266
  }
1267
1267
  getFilters(){
1268
1268
  this.filters = extendObj(true,{},this.filteredValues,this.filters)
@@ -1,6 +1,7 @@
1
1
  import theme,{LINE_HEIGHT} from "$theme";
2
2
  import { StyleSheet } from "react-native";
3
3
  import {get as getSession} from "./Common/session";
4
+ import appConfig from "$capp/config";
4
5
 
5
6
  export const getRenderType = ()=>getSession("render-type");
6
7
 
@@ -182,4 +183,6 @@ export const getRowStyle = ({row,bordered,numColumns,rowData,isAccordion,isTable
182
183
  style.push(styles.noHorizontalBorder);
183
184
  }
184
185
  return style;
185
- }
186
+ }
187
+
188
+ export const willConvertFiltersToSQL = x=>!!appConfig.get("convertDatagridFiltersToSQL");
@@ -709,6 +709,7 @@ class DropdownComponent extends AppComponent {
709
709
  bindResizeEvents,
710
710
  left,
711
711
  right,
712
+ dialogProps,
712
713
  ...dropdownProps
713
714
  } = this.props;
714
715
 
@@ -935,7 +936,7 @@ class DropdownComponent extends AppComponent {
935
936
  r = React.isValidElement(t)? r = <>{t}{r}</> : r;
936
937
  }
937
938
  if(showAdd){
938
- return <>{r}<Icon {..._addIconProps} {...props}/></>
939
+ return <>{r}<Icon {..._addIconProps} {...props} style={[theme.styles.noMargin,theme.styles.noPadding,_addIconProps.style,props.style]}/></>
939
940
  }
940
941
  return r;
941
942
  }}
@@ -981,6 +982,7 @@ class DropdownComponent extends AppComponent {
981
982
  const isBigList = this.isBigList;
982
983
  const ListComponent = isBigList ? BigList : List;
983
984
  const autoFocus = canAutoFocusSearchField({visible,items:renderingItems});
985
+ dialogProps = defaultObj(dialogProps);
984
986
  return (
985
987
  <Fragment>
986
988
  {!withBottomSheet && isMob && anchor}
@@ -993,7 +995,8 @@ class DropdownComponent extends AppComponent {
993
995
  onDismiss={this.hide.bind(this)}
994
996
  contentStyle = {[{paddingVertical:0},restProps.contentStyle]}
995
997
  anchor={anchor}
996
- title = {defaultStr(label,text)+"[ "+self.state.data.length.formatNumber()+" ]"}
998
+ {...dialogProps}
999
+ title = {defaultStr(dialogProps.title,label,text)+"[ "+self.state.data.length.formatNumber()+" ]"}
997
1000
  subtitle = {selectedText}
998
1001
  style = {[restProps.style]}
999
1002
  contentProps = {{style:{flex:1}}}
@@ -0,0 +1,5 @@
1
+ // Copyright 2022 @fto-consult/Boris Fouomene. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style
3
+ // license that can be found in the LICENSE file.
4
+
5
+ /**** pour étendre les formFields, ils suffit d'override cet alias*/
@@ -0,0 +1,231 @@
1
+ // Copyright 2022 @fto-consult/Boris Fouomene. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style
3
+ // license that can be found in the LICENSE file.
4
+
5
+ import Dropdown from "$ecomponents/Dropdown";
6
+ import {defaultStr,isFunction,defaultVal,isObjOrArray,defaultObj} from "$utils";
7
+ import PropTypes from "prop-types";
8
+ import actions from "$cactions";
9
+ import {navigateToTableData} from "$enavigation/utils";
10
+ import {getFetchOptions,prepareFilters} from "$cutils/filters";
11
+ import fetch from "$capi"
12
+ import {willConvertFiltersToSQL} from "$ecomponents/Datagrid/utils";
13
+ import React from "$react";
14
+
15
+ /*** la tabledataSelectField permet de faire des requêtes distantes pour rechercher les données
16
+ * Elle doit prendre en paramètre et de manière requis : les props suivante :
17
+ * foreignKeyColumn : La colonne dont le champ fait référence à la clé étrangère, ie fKeyTable dans laquelle faire les requêtes fetch
18
+ * foreignKeyTable : la tableData dans laquelle effectuer les donées de la requêtes
19
+ * foreignKeyLabel : Le libélé dans la table étrangère
20
+ */
21
+ const TableDataSelectField = React.forwardRef((_props,ref)=>{
22
+ let {foreignKeyColumn,foreignKeyTable,foreignKeyLabel,dropdownActions,fields,fetchItems,convertFiltersToSQL,mutateFetchedItems,getForeignKeyTable,onFetchItems,isFilter,isUpdate,isDocEditing,items,onAddProps,fetchDataOpts,...props} = _props;
23
+ props = defaultObj(props);
24
+ props.data = defaultObj(props.data);
25
+ foreignKeyColumn = foreignKeyColumn.trim();
26
+ foreignKeyLabel = defaultStr(foreignKeyLabel).trim();
27
+ convertFiltersToSQL = defaultVal(convertFiltersToSQL,willConvertFiltersToSQL());
28
+ const fKeyTable = getForeignKeyTable(foreignKeyTable,props)
29
+ if(!isObj(fKeyTable) || !(defaultStr(fKeyTable.tableName,fKeyTable.table))){
30
+ console.error("type de données invalide pour la fKeyTable ",fKeyTable," composant SelectTableData",_props);
31
+ return null;
32
+ }
33
+ foreignKeyTable = defaultStr(fKeyTable.tableName,fKeyTable.table,foreignKeyTable).trim().toUpperCase();
34
+ const isMounted = React.useIsMounted();
35
+ const showAdd = isFilter ? false : React.useRef(Auth.isTableDataAllowed({foreignKeyTable,action:'create'}) ? defaultVal(props.showAdd,props.showAddBtn,true) : false).current;
36
+ const [state,setState] = React.useState({
37
+ items : [],isLoading : true,
38
+ });
39
+ fetchDataOpts = Object.assign({},fetchDataOpts);
40
+ fetchItems = typeof fetchItems =='function' ? fetchItems : typeof fKeyTable.queryPath =='string' ? (opts)=>{
41
+ return fetch(fKeyTable.queryPath,opts);
42
+ } : undefined;
43
+ isUpdate = defaultBool(isUpdate,typeof isDocEditing ==='function' && isDocEditing({data:props.data,fKeyTable,foreignKeyTable}));
44
+ if(isFilter){
45
+ isUpdate = false;
46
+ }
47
+ const defaultFields = [foreignKeyColumn];
48
+ if(foreignKeyLabel){
49
+ defaultFields.push(foreignKeyLabel);
50
+ }
51
+ if(fetchDataOpts.fields !== 'all' && (!Array.isArray(fetchDataOpts.fields) || !fetchDataOpts.fields.length)){
52
+ fetchDataOpts.fields = defaultFields;
53
+ }
54
+ const foreignKeyColumnValue = props.defaultValue;
55
+ let isDisabled = defaultBool(props.disabled,props.readOnly,false);
56
+ if(!isDisabled && props.editable === false){
57
+ isDisabled = true;
58
+ }
59
+ if(isUpdate && isNonNullString(foreignKeyColumnValue) && (isDisabled)){
60
+ fetchDataOpts.selector = defaultObj(fetchDataOpts.selector);
61
+ fetchDataOpts.selector.$and = defaultArray(fetchDataOpts.selector.$and);
62
+ let hasF = false;
63
+ for(let i in fetchDataOpts.selector.$and){
64
+ const cFilter = fetchDataOpts.selector.$and[i];
65
+ if(isObj(cFilter)) {
66
+ if(cFilter[foreignKeyColumn] === foreignKeyColumnValue){
67
+ hasF = true;
68
+ break;
69
+ }
70
+ }
71
+ }
72
+ if(!hasF){
73
+ fetchDataOpts.selector.$and.push({[foreignKeyColumn] : foreignKeyColumnValue})
74
+ }
75
+ }
76
+ React.useEffect(()=>{
77
+ const onUpsertData = ()=>{return isMounted()?context.refresh():undefined};
78
+ APP.on(actions.upsert(foreignKeyTable),onUpsertData);
79
+ APP.on(actions.onRemove(foreignKeyTable),onUpsertData);
80
+ context.refresh();
81
+ return ()=>{
82
+ APP.off(actions.upsert(foreignKeyTable),onUpsertData);
83
+ APP.off(actions.onRemove(foreignKeyTable),onUpsertData);
84
+ };
85
+ },[]);
86
+
87
+ let dat = isNonNullString(foreignKeyColumnValue)? {
88
+ [foreignKeyColumn]:foreignKeyColumnValue,
89
+ ...(foreignKeyLabel ? {[foreignKeyLabel]:foreignKeyColumnValue+", introuvable dans le système"}:{})
90
+ } : null;
91
+
92
+ const context = {
93
+ refresh : (force,cb)=>{
94
+ if(!isMounted()) return;
95
+ let opts = Object.clone(fetchDataOpts);
96
+ opts.selector = prepareFilters(fetchDataOpts.selector,{convertToSQL:convertFiltersToSQL});
97
+ opts = getFetchOptions(opts);
98
+ const r = fetchItems && fetchItems(opts);
99
+ if(isPromise(r)){
100
+ r.then((args)=>{
101
+ if(Array.isArray(args)){
102
+ args = {data : args};
103
+ }
104
+ let items = args.items = args.data = Array.isArray(args.items) ? args.items : Array.isArray(args.data) ? args.data : [];
105
+ if(dat && isUpdate){
106
+ if(isFunction(mutateFetchedItems)){
107
+ items = mutateFetchedItems(items);
108
+ }
109
+ let hasFound = false;
110
+ if(!isObjOrArray(items)) items = [];
111
+ for(let i in items){
112
+ if(isObj(items[i]) && items[i][foreignKeyColumn] == foreignKeyColumnValue){
113
+ hasFound = true;
114
+ break;
115
+ }
116
+ }
117
+ if(!hasFound){
118
+ if(Array.isArray(items)){
119
+ items.push(dat);
120
+ } else {
121
+ items[foreignKeyColumnValue] = dat;
122
+ }
123
+ }
124
+ }
125
+ setState({...state,items,isLoading:false})
126
+ if(onFetchItems){
127
+ onFetchItems({data:items,items,context,props});
128
+ }
129
+ }).catch((e)=>{
130
+ console.log(e," fetching list of data select table data ",foreignKeyColumn,foreignKeyTable)
131
+ })
132
+ } else {
133
+ setState({...state, isLoading : false})
134
+ }
135
+ }
136
+ }
137
+ const prevIsUpdate = React.usePrevious(isUpdate);
138
+ const prevDefaultValue = React.usePrevious(foreignKeyColumnValue);
139
+ if(!isFilter){
140
+ React.useEffect(()=>{
141
+ if(prevIsUpdate === isUpdate && JSON.stringify(prevDefaultValue) === JSON.stringify(foreignKeyColumnValue)) return;
142
+ context.refresh();
143
+ },[isUpdate,foreignKeyColumnValue])
144
+ }
145
+ dropdownActions = isObj(dropdownActions)? {...dropdownActions} : isArray(dropdownActions)? [...dropdownActions] : []
146
+ const isDropdonwsActionsArray = isArray(dropdownActions);
147
+ const refreshItem = {
148
+ text : 'Rafraichir',
149
+ onPress : context.refresh,
150
+ icon : 'refresh',
151
+ }
152
+ if(isDropdonwsActionsArray){
153
+ dropdownActions.push(refreshItem)
154
+ } else {
155
+ dropdownActions.trefreshItem = refreshItem;
156
+ }
157
+ const rItem = (p)=>{
158
+ if(!isObj(p) || !isObj(p.item)) return null;
159
+ const itemLabel = defaultStr(foreignKeyLabel && p.item[foreignKeyLabel]), itemCode = defaultStr(p.item[foreignKeyColumn]);
160
+ return (itemLabel !== itemCode ? ((isNonNullString(itemCode)?("["+itemCode+"] "):"")+itemLabel):itemLabel);
161
+ }
162
+ const dialogProps = defaultObj(props.dialogProps);
163
+ dialogProps.title = defaultStr(dialogProps.title,fKeyTable.text,fKeyTable.label)
164
+ return <Dropdown
165
+ {...props}
166
+ isFilter = {isFilter}
167
+ showAdd = {!isFilter && showAdd}
168
+ {...React.setProps(Dropdown,fKeyTable,{})}
169
+ {...state}
170
+ dialogProps = {dialogProps}
171
+ ref = {ref}
172
+ defaultValue = {foreignKeyColumnValue}
173
+ dropdownActions = {dropdownActions}
174
+ context = {context}
175
+ itemValue = {(p) => {
176
+ if(typeof props.itemValue ==='function'){
177
+ return props.itemValue(p);
178
+ }
179
+ return p.item[foreignKeyColumn];
180
+ }}
181
+ renderItem = {(p) => {
182
+ if(typeof props.renderItem ==='function'){
183
+ return props.renderItem(p);
184
+ }
185
+ if(typeof props.renderText =='function'){
186
+ return props.renderText(p);
187
+ }
188
+ return rItem(p);
189
+ }}
190
+ renderText = {(p) => {
191
+ if(typeof props.renderText ==='function'){
192
+ return props.renderText(p);
193
+ }
194
+ if(typeof props.renderItem ==='function'){
195
+ return props.renderItem(p);
196
+ }
197
+ return rItem(p);
198
+ }}
199
+ hideOnAdd
200
+ onAdd = {({onGoBack})=>{
201
+ onAddProps = defaultObj(isFunction(onAddProps)? onAddProps.call(context,{context,foreignKeyTable,dbName,props}) : onAddProps);
202
+ return navigateToTableData({...onAddProps,tableName : foreignKeyTable,onGoBack})
203
+ }}
204
+ />
205
+ });
206
+
207
+ TableDataSelectField.propTypes = {
208
+ ...Dropdown.propTypes,
209
+ mutateFetchedItems : PropTypes.func, //la fonction permettant d'effectuer une mutation sur l'ensemble des donnéees récupérées à distance
210
+ fetchItems : PropTypes.func,//la fonction de rappel à utiliser pour faire une requête fetch permettant de selectionner les données à distance
211
+ foreignKeyColumn : PropTypes.string.isRequired,//le nom de la clé étrangère à laquelle fait référence la colone dans la fKeyTable
212
+ foreignKeyLabel : PropTypes.string,
213
+ getForeignKeyTable : PropTypes.func.isRequired, //la fonction permettant de récupérer la fKeyTable data dont fait référence le champ
214
+ foreignKeyTable : PropTypes.string, //le nom de la fKeyTable data à laquelle se reporte le champ
215
+ onFetchItems : PropTypes.func,
216
+ fetchDataOpts : PropTypes.shape({
217
+ fields : PropTypes.oneOfType([
218
+ PropTypes.string,
219
+ PropTypes.bool,
220
+ PropTypes.array,
221
+ ])
222
+ }),
223
+ itemValue : PropTypes.func,
224
+ renderItem : PropTypes.func,
225
+ renderText : PropTypes.func,
226
+ convertFiltersToSQL : PropTypes.func,// si l'on doit convertir les selecteurs de filtres au format SQl
227
+ }
228
+
229
+ export default TableDataSelectField;
230
+
231
+ TableDataSelectField.displayName = "TableDataSelectField";
@@ -1,5 +1,5 @@
1
- import SelectField from "./SelectField";
2
- import SelectTableData from "$containers/TableData/SelectField";
1
+ import SelectField from "../SelectField";
2
+ import SelectTableData from "./Component";
3
3
 
4
4
  export default class FormSelectTableDataField extends SelectField{
5
5
  _render(props){
@@ -3,6 +3,7 @@ import TextField from "./TextField";
3
3
  import SelectField from "./SelectField";
4
4
  import Switch from "./Switch";
5
5
  import Checkbox from "./Checkbox";
6
+ import SelectTableData from "./SelectTableData";
6
7
  //import IdField from "./IdField";
7
8
  //import PieceField from "./PieceField";
8
9
  import Slider from "./Slider";
@@ -14,11 +15,17 @@ import Image from "./Image";
14
15
  import Tel from "./Tel";
15
16
  import SelectCountry from "./SelectCountry";
16
17
  import Html from "./Html";
18
+ import * as eFormFields from "$extendFormFields";
19
+ import "$utils";
20
+ import React from "$react";
17
21
 
18
- export default {
22
+ export * from "$extendFormFields";
23
+
24
+ const defFormFields = {
19
25
  Field,
20
26
  TextField,
21
27
  SelectField,
28
+ SelectTableData,
22
29
  SelectCountry
23
30
  ,Switch
24
31
  ,Checkbox
@@ -34,10 +41,20 @@ export default {
34
41
  ,Html
35
42
  }
36
43
 
44
+ //pour étendre les FormFields par défaut
45
+ Object.map(eFormFields,(F,i)=>{
46
+ if(React.isComponent(F)){
47
+ defFormFields[i] = F;
48
+ }
49
+ })
50
+
51
+ export default defFormFields;
52
+
37
53
  export {
38
54
  Field,
39
55
  TextField,
40
56
  SelectField,
57
+ SelectTableData,
41
58
  SelectCountry
42
59
  ,Switch
43
60
  ,Checkbox
@@ -149,7 +149,6 @@ export default class FormDataComponent extends AppComponent{
149
149
  return this.props.isDocUpdate({data,context:this}) ? true : false;
150
150
  }
151
151
  return false;
152
- //return isDocUpdate(data) ? true : false;
153
152
  }
154
153
  canBindResizeEvents(){
155
154
  return false;
@@ -31,18 +31,12 @@ export default class FormDataActionComponent extends FormData {
31
31
  const mainProps = this.getMainProps();
32
32
  const data = this.getDataProp();
33
33
  const appBarProps = Object.assign({},mainProps.appBarProps);
34
- const indexField = this.getIndexFieldProps();
35
34
  const isEditing = this.isDocEditing(data);
36
35
  let subtitle = (isEditing?'Modifier':this.getNewElementLabel());
37
36
  let title = React.getTextContent(defaultVal(appBarProps.title,mainProps.title,this.props.title));
38
37
  if(isEditing){
39
- let _title = "";
40
- if(isNonNullString(indexField)){
41
- _title = defaultStr(data[indexField]);
42
- } else if(isNonNullString(data.code)){
43
- _title = data.code;
44
- }
45
- if(_title){
38
+ let _title = this.getPrimaryKeysFieldsValueText(data);
39
+ if(isNonNullString(_title)){
46
40
  subtitle+= " ["+_title+"]"
47
41
  }
48
42
  } else {
@@ -88,6 +82,12 @@ export default class FormDataActionComponent extends FormData {
88
82
  canCreateNew(){
89
83
  return true;
90
84
  }
85
+ /*** permet de récupérer le contenu textuel associé à la données en cours de modification, pour les clés primaires */
86
+ getPrimaryKeysFieldsValueText(data){
87
+ data = defaultObj(data);
88
+ const indexField = this.getIndexFieldProps();
89
+ return isNonNullString(indexField) && isNonNullString(data[indexField])? data[indexField] : isNonNullString(data.code)? data.code : undefined;
90
+ }
91
91
  getAppBarActionsProps(props){
92
92
  props = defaultObj(props,this.getMainProps(),this.props);
93
93
  let {actions,save2NewAction,save2printAction,save2closeAction,saveAction,newAction} = props;
@@ -102,10 +102,9 @@ export default class FormDataActionComponent extends FormData {
102
102
  const isEditing = this.isDocEditing(data);
103
103
  let textSave = isEditing ? "Modifier": 'Enregistrer';
104
104
  const newElementLabel = defaultStr(props.newElementLabel,this.props.newElementLabel,"Nouvel Element");
105
- const indexField = this.getIndexFieldProps();
106
105
  if(isEditing){
107
- const t = isNonNullString(indexField) && isNonNullString(data[indexField])? data[indexField] : isNonNullString(data.code)? data.code : undefined;
108
- if(t){
106
+ const t = this.getPrimaryKeysFieldsValueText(data);
107
+ if(isNonNullString(t)){
109
108
  textSave+="["+t+"]"
110
109
  }
111
110
  }
@@ -7,6 +7,8 @@ import React from "$react";
7
7
  const componentTypes = {
8
8
  ...Fields,
9
9
  id : Fields.IdField,
10
+ selecttabledata : Fields.SelectTableData,
11
+ select_tabledata : Fields.SelectTableData,
10
12
  idfield : Fields.IdField,
11
13
  piecefield : Fields.PieceField,
12
14
  piece : Fields.PieceField,
@@ -78,17 +80,9 @@ export const getFilterComponentProps = (_props)=>{
78
80
  component = Fields.SelectField;
79
81
  if(type =='select_country' || type =='selectcountry'){
80
82
  component = Fields.SelectCountry;
83
+ } else if(type =='select_tabledata' || type =='selecttabledata'){
84
+ component = Fields.SelectTableData;
81
85
  }
82
- /*if(type !== 'select'){
83
- if(type === 'selectstructdata') {
84
- dbName = 'structData';
85
- component = StructDataSelectField;
86
- } else if(type === 'selecttabledata'){
87
- component = TableDataSelectField;
88
- }
89
- props.tableName = tableName;
90
- props.dbName = dbName;
91
- }*/
92
86
  type = "select";
93
87
  } else if(type == 'switch' || type =='radio' || type ==='checkbox') {
94
88
  type = 'select';
@@ -43,10 +43,13 @@ export default class TableDataScreenComponent extends FormDataScreen{
43
43
  data : hasManyData ? defaultObj(cDatas[0]) : isObj(mainProps.data)? mainProps.data : {}
44
44
  });
45
45
  const table = defaultObj(mainProps.table);
46
- const fields = {};
46
+ const fields = {},primaryKeyFields = {};
47
47
  Object.map(table.fields,(field,i)=>{
48
48
  if(isObj(field) && field.form !== false){
49
49
  fields[i] = Object.clone(field);
50
+ if(field.primary === true){
51
+ primaryKeyFields[field.field || i] = true;
52
+ }
50
53
  } else {
51
54
  fields[i] = field;
52
55
  }
@@ -63,7 +66,13 @@ export default class TableDataScreenComponent extends FormDataScreen{
63
66
  titleProp : {value : mainProps.title},
64
67
  closeOnSaveProp : {value : mainProps.closeOnSave || mainProps.closeAfterSave },
65
68
  newActionProp : {value : mainProps.newAction},
66
-
69
+ //la liste des champ de type clé primaire associés à la table
70
+ primaryKeyFields : {value : primaryKeyFields},
71
+ cloneProp : {value : typeof mainProps.clone =='function' && mainProps.clone || undefined},
72
+ printProp : {value : typeof mainProps.print =='function' && mainProps.print || undefined},
73
+ archiveProp : {value : typeof mainProps.archive =='function' && mainProps.archive || undefined },
74
+ testIDProp : {value : defaultStr(mainProps.testID)},
75
+ isDocEditingProp : {value : typeof mainProps.isDocEditing =='function'? mainProps.isDocEditing : typeof mainProps.isDocUpdate =='function'? mainProps.isDocUpdate : undefined}
67
76
  });
68
77
  this.hidePreloader = this.hidePreloader.bind(this);
69
78
  this.showPreloader = this.showPreloader.bind(this);
@@ -256,7 +265,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
256
265
  const restProps = this.getCurrentEditingProps();
257
266
  delete restProps.tabs;
258
267
  let {tabProps,firstTabProps,tabsProps,withScrollView} = restProps;
259
- let testID = defaultStr(this.props.testID);
268
+ let testID = this.testIDProp;
260
269
  tabsProps = defaultObj(tabsProps);
261
270
  tabsProps.tabItemsProps = defaultObj(tabsProps.tabItemsProps);
262
271
  if(typeof withScrollView =='boolean' && typeof tabsProps.withScrollView !=='boolean'){
@@ -385,10 +394,40 @@ export default class TableDataScreenComponent extends FormDataScreen{
385
394
  isPrintable(){
386
395
  return false;
387
396
  }
397
+ /*** retourne la liste des valeurs de clé primarire associés à la table data pour la données en cours de modification
398
+ * Elle permet d'afficher dans la barre de titre, les identifiants de la table de données en cours de modification
399
+ */
400
+ getPrimaryKeysFieldsValueText(data){
401
+ data = defaultObj(data,this.getCurrentData());
402
+ const v = [];
403
+ Object.map(this.primaryKeyFields,(vv,f)=>{
404
+ if(typeof data[f] =='number' || (typeof data[f] =='string' && data[f])){
405
+ v.push(data[f]);
406
+ }
407
+ });
408
+ return v.join(" ");
409
+ }
410
+ isDocEditing(data){
411
+ data = defaultObj(data);
412
+ if(!this.isDocEditingProp){
413
+ let hasPrimaryFields = false;
414
+ let hasValidated = true;
415
+ Object.map(this.primaryKeyFields,(v,f)=>{
416
+ hasPrimaryFields = true;
417
+ if(!(f in data) || (data[f] == null) || (!data[f] && typeof data !=='number')){
418
+ hasValidated = false;
419
+ }
420
+ });
421
+ if(hasPrimaryFields){
422
+ return hasValidated;
423
+ }
424
+ }
425
+ return super.isDocEditing(data);
426
+ }
388
427
  print(data){
389
- if(!this.isPrintable() && typeof this.props.print!=='function') return;
428
+ if(!this.isPrintable() && typeof this.printProp!=='function') return;
390
429
  data = this.isDocEditing(data)? data : isObj(data) && this.isDocEditing(data.data)? data.data : {};
391
- return this.props.print(data,this);
430
+ return this.printProp(data,this);
392
431
  }
393
432
  isClonable(){
394
433
  return true;
@@ -396,7 +435,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
396
435
  clone (data){
397
436
  if(!this._isMounted() || !this.isClonable())return data;
398
437
  data = {...this.getCurrentEditingData(data)};
399
- if(typeof this.props.clone =='function' && this.props.clone(data,this) === false) return data;
438
+ if(this.cloneProp && this.cloneProp(data,this) === false) return data;
400
439
  this.showPreloader();
401
440
  delete data.approved;
402
441
  Object.map(['_rev','_id','code','updatedBy','updatedDate','createdBy','updatedHour','createdHour','createdDate'],(idx)=>{