@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.
- package/babel.config.alias.js +4 -0
- package/package.json +2 -2
- package/src/components/Countries/SelectCountry.js +1 -0
- package/src/components/Datagrid/Common/Common.js +2 -2
- package/src/components/Datagrid/utils.js +4 -1
- package/src/components/Dropdown/index.js +5 -2
- package/src/components/Form/Fields/$extendFormFields.js +5 -0
- package/src/components/Form/Fields/SelectTableData/Component.js +231 -0
- package/src/components/Form/Fields/{SelectTableData.js → SelectTableData/index.js} +2 -2
- package/src/components/Form/Fields/index.js +18 -1
- package/src/components/Form/FormData/FormData.js +0 -1
- package/src/components/Form/FormData/FormDataActions.js +10 -11
- package/src/components/Form/FormData/componentsTypes.js +4 -10
- package/src/layouts/Screen/TableData.js +45 -6
package/babel.config.alias.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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,
|
|
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
|
-
|
|
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,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 "
|
|
2
|
-
import SelectTableData from "
|
|
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
|
|
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
|
|
@@ -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(
|
|
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 =
|
|
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 =
|
|
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.
|
|
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.
|
|
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(
|
|
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)=>{
|