@fto-consult/expo-ui 5.9.0 → 5.10.1
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 -1
- package/package.json +11 -11
- package/src/app.config.json +31 -0
- package/src/components/Datagrid/Accordion/index.js +3 -24
- package/src/components/Datagrid/Actions/Header.js +1 -1
- package/src/components/Datagrid/Actions/index.js +0 -1
- package/src/components/Datagrid/Common/Common.js +60 -64
- package/src/components/Datagrid/Dashboard/index.js +2 -1
- package/src/components/Datagrid/Table/index.js +3 -18
- package/src/components/Form/Fields/Field.js +1 -1
- package/src/components/Form/Fields/IDField.js +0 -1
- package/src/components/Form/Fields/SelectTableData/Component.js +9 -4
- package/src/components/InlineIndicator/Select.js +1 -0
- package/src/components/InlineIndicator/index.js +1 -1
- package/src/components/SimpleSelect/index.js +2 -2
- package/src/layouts/Screen/FormData/FormData.js +4 -1
- package/src/layouts/Screen/TableData.js +66 -49
- package/src/layouts/Screen/utils.js +10 -7
- package/src/navigation/Drawer/index.js +2 -1
- package/src/navigation/Drawer/items/utils.js +0 -0
package/babel.config.alias.js
CHANGED
|
@@ -39,8 +39,11 @@ module.exports = (opts)=>{
|
|
|
39
39
|
if(fs.existsSync(configPath)){
|
|
40
40
|
r["$package.json"] = r["$packageJSON"] = configPath;
|
|
41
41
|
}
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
r["$ecomponents"] = r["$expo-components"] = path.resolve(expo,"components");
|
|
44
|
+
r["$econfirm"] = path.resolve(r["$expo-components"],"Dialog","confirm");
|
|
45
|
+
r["$confirm"] = r["$confirm"] || r["$econfirm"];
|
|
46
|
+
r["$eauth"] = path.resolve(expo,"auth");
|
|
44
47
|
r["$etableLink"] = r["$eTableLink"] = path.resolve(r["$ecomponents"],"TableLink");
|
|
45
48
|
r.$tableLink = r.$TableLink = r.$tableLink || r.$TableLink || path.resolve(r.$etableLink,"default");
|
|
46
49
|
r["$components"] = r["$components"] || r["$ecomponents"];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fto-consult/expo-ui",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.10.1",
|
|
4
4
|
"description": "Bibliothèque de composants UI Expo,react-native",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -58,10 +58,10 @@
|
|
|
58
58
|
},
|
|
59
59
|
"homepage": "https://github.com/borispipo/expo-ui#readme",
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"@emotion/native": "^11.
|
|
61
|
+
"@emotion/native": "^11.11.0",
|
|
62
62
|
"@expo/html-elements": "^0.2.0",
|
|
63
63
|
"@expo/vector-icons": "^13.0.0",
|
|
64
|
-
"@fto-consult/common": "^3.
|
|
64
|
+
"@fto-consult/common": "^3.14.1",
|
|
65
65
|
"@gorhom/portal": "^1.0.14",
|
|
66
66
|
"@react-native-async-storage/async-storage": "^1.17.11",
|
|
67
67
|
"@react-native-community/datetimepicker": "^6.7.3",
|
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
"@react-navigation/native": "^6.1.6",
|
|
71
71
|
"@react-navigation/native-stack": "^6.9.12",
|
|
72
72
|
"@shopify/flash-list": "^1.4.0",
|
|
73
|
-
"apexcharts": "^3.
|
|
74
|
-
"expo": "^48.0.
|
|
73
|
+
"apexcharts": "^3.40.0",
|
|
74
|
+
"expo": "^48.0.17",
|
|
75
75
|
"expo-camera": "~13.2.1",
|
|
76
76
|
"expo-clipboard": "~4.1.1",
|
|
77
77
|
"expo-font": "~11.1.1",
|
|
@@ -91,20 +91,20 @@
|
|
|
91
91
|
"react-content-loader": "^6.2.1",
|
|
92
92
|
"react-dom": "^18.2.0",
|
|
93
93
|
"react-native": "^0.71.3",
|
|
94
|
-
"react-native-big-list": "^1.6.
|
|
94
|
+
"react-native-big-list": "^1.6.1",
|
|
95
95
|
"react-native-blob-util": "^0.17.0",
|
|
96
96
|
"react-native-gesture-handler": "~2.9.0",
|
|
97
97
|
"react-native-iphone-x-helper": "^1.3.1",
|
|
98
98
|
"react-native-mime-types": "^2.3.0",
|
|
99
|
-
"react-native-paper": "^5.
|
|
100
|
-
"react-native-paper-dates": "^0.
|
|
99
|
+
"react-native-paper": "^5.8.0",
|
|
100
|
+
"react-native-paper-dates": "^0.16.2",
|
|
101
101
|
"react-native-reanimated": "~2.14.4",
|
|
102
|
-
"react-native-safe-area-context": "^4.5.
|
|
103
|
-
"react-native-screens": "
|
|
102
|
+
"react-native-safe-area-context": "^4.5.3",
|
|
103
|
+
"react-native-screens": "^3.20.0",
|
|
104
104
|
"react-native-svg": "13.4.0",
|
|
105
105
|
"react-native-web": "~0.18.7",
|
|
106
106
|
"react-native-webview": "^11.26.0",
|
|
107
|
-
"react-virtuoso": "^4.
|
|
107
|
+
"react-virtuoso": "^4.3.7",
|
|
108
108
|
"sharp-cli": "^2.1.0",
|
|
109
109
|
"tippy.js": "^6.3.7",
|
|
110
110
|
"websql": "^2.0.3",
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "SALITE",
|
|
3
|
+
"version": "7.0.0",
|
|
4
|
+
"description": "Logiciel de gestion commerciale pour PME",
|
|
5
|
+
"realeaseDateStr": "1er Juin 2021",
|
|
6
|
+
"releaseDate": "2020-05-23",
|
|
7
|
+
"devMail": "saliteapp@gmail.com",
|
|
8
|
+
"devWebsite": "http://fto-consulting.com/salite/",
|
|
9
|
+
"copyRight": "firsto consulting@Jan 2020",
|
|
10
|
+
"id": "com.ftc.apps.salite7",
|
|
11
|
+
"pouchdbNamePrefix": "com.ftc.apps.slite-",
|
|
12
|
+
"includeFieldsInDatagridFetchOptions": false,
|
|
13
|
+
"feeds": {
|
|
14
|
+
"VIDEOS": {
|
|
15
|
+
"link": "http://fto-consulting.com/salite/feeds",
|
|
16
|
+
"label": "Bibliothèque vidéo",
|
|
17
|
+
"provider": "",
|
|
18
|
+
"icon": "file-video"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"theme": {
|
|
22
|
+
"light": {
|
|
23
|
+
"primary": "#0073B1",
|
|
24
|
+
"secondary": "#EC008C",
|
|
25
|
+
"primaryOnSurface": "#0073B1",
|
|
26
|
+
"secondaryOnSurface": "#EC008C"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"author": "@fto-consulting",
|
|
30
|
+
"license": "ISC"
|
|
31
|
+
}
|
|
@@ -315,8 +315,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
315
315
|
isLoading:customIsLoading,
|
|
316
316
|
cacheHeight,
|
|
317
317
|
toggleFilters,
|
|
318
|
-
|
|
319
|
-
dbSelectorProps,
|
|
318
|
+
dataSourceSelector,
|
|
320
319
|
progressBarProps,
|
|
321
320
|
accordion,
|
|
322
321
|
preloaderProps,
|
|
@@ -363,26 +362,6 @@ const DatagridFactory = (Factory)=>{
|
|
|
363
362
|
color: titleColor,
|
|
364
363
|
style : [styles.title,rStyles.lineHeight,titleProps.style]
|
|
365
364
|
}
|
|
366
|
-
|
|
367
|
-
let showDBSelector = false;
|
|
368
|
-
if(dbSelector === true){
|
|
369
|
-
showDBSelector = true;
|
|
370
|
-
}
|
|
371
|
-
dbSelectorProps = defaultObj(dbSelectorProps);
|
|
372
|
-
let title = this.props.title;
|
|
373
|
-
let _dbSelector = undefined;/* showDBSelector ? <div>
|
|
374
|
-
<DBSelector
|
|
375
|
-
{...dbSelectorProps}
|
|
376
|
-
onChange = {this.onChangeDatabases.bind(this)}
|
|
377
|
-
/>
|
|
378
|
-
</div> : null;*/
|
|
379
|
-
if(!title){
|
|
380
|
-
title = _dbSelector;
|
|
381
|
-
_dbSelector = null;
|
|
382
|
-
}
|
|
383
|
-
exportable = defaultBool(exportable,true);
|
|
384
|
-
let exportTableProps = this.getExportableProps();
|
|
385
|
-
|
|
386
365
|
filter = defaultFunc(filter,x=>true);
|
|
387
366
|
const showFooters = this.canShowFooters();
|
|
388
367
|
let restItems = [];
|
|
@@ -422,7 +401,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
422
401
|
const datagridHeader = <View testID={testID+"_HeaderContainer"} pointerEvents={pointerEvents} style={[styles.datagridHeader]}>
|
|
423
402
|
<ScrollView testID={testID+"_HeaderScrollView"} horizontal contentContainerStyle={StyleSheet.flatten([styles.contentContainerStyle,styles.minW100])}>
|
|
424
403
|
<View testID={testID+"_HeaderContentCntainer"} style={[styles.table,styles.pullRight]}>
|
|
425
|
-
{
|
|
404
|
+
{/*this.renderDataSourceSelector()*/}
|
|
426
405
|
<View testID={testID+"_HeaderQueryLimit"} style={[styles.paginationItem]}>
|
|
427
406
|
{this.renderQueryLimit(this.getStateDataSize().formatNumber())}
|
|
428
407
|
</View>
|
|
@@ -528,7 +507,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
528
507
|
{this.props.showActions !== false ? <DatagridActions
|
|
529
508
|
testID={testID+"_Actions"}
|
|
530
509
|
pointerEvents = {pointerEvents}
|
|
531
|
-
title = {
|
|
510
|
+
title = {this.renderDataSourceSelector()}
|
|
532
511
|
context = {this}
|
|
533
512
|
selectedRows = {Object.assign({},this.selectedRows)}
|
|
534
513
|
selectedRowsActions = {this.renderSelectedRowsActions.bind(this)}
|
|
@@ -13,7 +13,7 @@ const selectedTitle ='#f50057';
|
|
|
13
13
|
export const getSelectedBackgroundColor = x=> theme.isDark()?theme.colors.surface : selectedBackgroundColor;
|
|
14
14
|
|
|
15
15
|
export default function DatagridActionsHeaderComponent({title,selected,testID,children,style,pointerEvents,...props}) {
|
|
16
|
-
title =
|
|
16
|
+
title = React.isValidElement(title,true)? title : "";
|
|
17
17
|
const bStyle = selected && theme.isDark()? {
|
|
18
18
|
borderBottomColor : theme.colors.divider,
|
|
19
19
|
borderTopColor : theme.colors.divider,
|
|
@@ -9,7 +9,6 @@ import theme from "$theme"
|
|
|
9
9
|
import Button from "$ecomponents/Button";
|
|
10
10
|
import { StyleSheet } from "react-native";
|
|
11
11
|
import Label from "$ecomponents/Label";
|
|
12
|
-
import APP from "$capp/instance";
|
|
13
12
|
import { useWindowDimensions } from "react-native";
|
|
14
13
|
|
|
15
14
|
export default function DatagridActions (_props){
|
|
@@ -40,6 +40,7 @@ import Button from "$ecomponents/Button";
|
|
|
40
40
|
import stableHash from "stable-hash";
|
|
41
41
|
import * as XLSX from "xlsx";
|
|
42
42
|
import {convertToSQL} from "$ecomponents/Filter";
|
|
43
|
+
import appConfig from "$capp/config";
|
|
43
44
|
|
|
44
45
|
export const TIMEOUT = 100;
|
|
45
46
|
|
|
@@ -339,39 +340,8 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
339
340
|
windowHeight,
|
|
340
341
|
}
|
|
341
342
|
this.selectableColumnRef = React.createRef(null);
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
isPv = this.props.dataSourceSelector !== false;
|
|
345
|
-
} else isPv = this.props.dataSourceSelector === true ? true : false;
|
|
346
|
-
if(isPv){
|
|
347
|
-
let dataSourceSelectorProps = defaultObj(this.props.dataSourceSelectorProps);
|
|
348
|
-
['table','tableName'].map((tb,idx)=>{
|
|
349
|
-
dataSourceSelectorProps[tb] = defaultStr(this.props[tb],dataSourceSelectorProps[tb]);
|
|
350
|
-
});
|
|
351
|
-
let cDB = []//DBSelector.getDefaultSelected(dataSourceSelectorProps,this.currentDataSources,this.props);
|
|
352
|
-
let sDB = this.getSessionData().selectedDataSources;
|
|
353
|
-
cDB = Object.toArray(cDB);
|
|
354
|
-
if(cDB.length){
|
|
355
|
-
this.currentDataSources = cDB
|
|
356
|
-
} else {
|
|
357
|
-
this.currentDataSources = sDB;
|
|
358
|
-
}
|
|
359
|
-
this.setSessionData({selectedDataSources:this.currentDataSources});
|
|
360
|
-
} else {
|
|
361
|
-
this.currentDataSources = Object.toArray(this.currentDataSources);
|
|
362
|
-
}
|
|
363
|
-
if(isPv){
|
|
364
|
-
isPv = this.props.dataSourceSelector !== false;
|
|
365
|
-
} else isPv = this.props.dataSourceSelector === true ? true : false;
|
|
366
|
-
if(isPv){
|
|
367
|
-
let dataSourceSelectorProps = defaultObj(this.props.dataSourceSelectorProps);
|
|
368
|
-
['table','tableName'].map((tb)=>{
|
|
369
|
-
dataSourceSelectorProps[tb] = defaultStr(this.props[tb],this[tb],dataSourceSelectorProps[tb]);
|
|
370
|
-
});
|
|
371
|
-
this.setSessionData({selectedDataSources:this.currentDataSources});
|
|
372
|
-
} else {
|
|
373
|
-
this.currentDataSources = Object.toArray(this.currentDataSources);
|
|
374
|
-
}
|
|
343
|
+
this.currentDataSources = Object.toArray(this.getSessionData().selectedDataSources);
|
|
344
|
+
this.setSessionData({selectedDataSources:this.currentDataSources});
|
|
375
345
|
this.persistDisplayType(this.state.displayType);
|
|
376
346
|
}
|
|
377
347
|
/*** si l'on peut récuperer à distance, les colonnes seulement visibles */
|
|
@@ -621,13 +591,13 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
621
591
|
return this.selectedRowsCount <= 1 ? true : false;
|
|
622
592
|
}
|
|
623
593
|
/**** fonction appelée lorsque l'on clique sur la checkbox permettant de sélectionner la ligne */
|
|
624
|
-
handleRowToggle ({
|
|
625
|
-
if(
|
|
626
|
-
|
|
594
|
+
handleRowToggle ({rowIndex,rowKey,index, selected,cb,callback},cb2){
|
|
595
|
+
if((typeof rowKey !=='string' && typeof rowKey !=='number')) return false;
|
|
596
|
+
const row = this.getRowByKey(rowKey);
|
|
597
|
+
if(!isObj(row) || !this.canSelectRow(row)) return false;
|
|
627
598
|
let selectableMultiple = this.isSelectableMultiple();
|
|
628
599
|
rowIndex = defaultNumber(rowIndex,index);
|
|
629
600
|
cb = defaultFunc(cb,callback,cb2)
|
|
630
|
-
row = rowData = defaultObj(row,rowData);
|
|
631
601
|
const size = this.selectedRowsCount;
|
|
632
602
|
if(selected && !this.canSelectCheckedRow()){
|
|
633
603
|
notify.warning("Vous ne pouvez sélectionner plus d'un élément");
|
|
@@ -655,14 +625,13 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
655
625
|
this.selectedRowsCount = Math.max(this.selectedRowsCount-1,0);
|
|
656
626
|
delete selectedRows[rowKey];
|
|
657
627
|
}
|
|
658
|
-
|
|
659
628
|
this.toggleSelectableColumnCheckbox();
|
|
660
629
|
if(isObj(this.datagridActionsContext) && isFunction(this.datagridActionsContext.setSelectedRows)){
|
|
661
630
|
this.datagridActionsContext.setSelectedRows(selectedRows,x =>{
|
|
662
631
|
this.callSRowCallback({selected,row,rowIndex,rowKey,cb})
|
|
663
632
|
});
|
|
664
633
|
} else {
|
|
665
|
-
this.callSRowCallback({selected,rowData,row,rowIndex,rowKey,cb});
|
|
634
|
+
this.callSRowCallback({selected,rowData:row,row,rowIndex,rowKey,cb});
|
|
666
635
|
}
|
|
667
636
|
return true;
|
|
668
637
|
}
|
|
@@ -1054,6 +1023,25 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1054
1023
|
}
|
|
1055
1024
|
return null;
|
|
1056
1025
|
}
|
|
1026
|
+
renderDataSourceSelector(){
|
|
1027
|
+
const t = isNonNullString(this.props.title)? <Label testID={"RN_DatagridTitleProp"}>{this.props.title}</Label> : React.isValidElement(this.props.title)? this.props.title : null;
|
|
1028
|
+
const table = defaultStr(this.props.table,this.props.tableName);
|
|
1029
|
+
const dS = dS === false ? null : typeof this.props.dataSourceSelector ==='function'? this.props.dataSourceSelector({
|
|
1030
|
+
defaultValue : this.currentDataSources,
|
|
1031
|
+
onChange : this.onChangeDataSources.bind(this),
|
|
1032
|
+
tableName:table,
|
|
1033
|
+
table,
|
|
1034
|
+
isAccordion : this.isAccordion,
|
|
1035
|
+
context : this,
|
|
1036
|
+
}) : null;
|
|
1037
|
+
if(React.isValidElement(dS)){
|
|
1038
|
+
return <View testID={'RN_Datagrid_DataSourceSelectorContainer'} style={[theme.styles.flex,theme.styles.flexRow,theme.styles.justifyContentFlexStart,theme.styles.alignItemsCenter]}>
|
|
1039
|
+
{dS}
|
|
1040
|
+
{t}
|
|
1041
|
+
</View>
|
|
1042
|
+
}
|
|
1043
|
+
return t;
|
|
1044
|
+
}
|
|
1057
1045
|
/*** permet de faire le rendu de certaines entête personalisés
|
|
1058
1046
|
* utile lorsque l'on veut par exemple afficher d'autres information au niveau de l'entête du tableau
|
|
1059
1047
|
*/
|
|
@@ -2716,7 +2704,9 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
2716
2704
|
const canUpdateFooters = !!(updateFooters !== false && hasFootersFields);
|
|
2717
2705
|
this.hasFoundSectionData.current = false;
|
|
2718
2706
|
this.sectionListDataSize.current = 0;
|
|
2707
|
+
this.rowsByKeys = {};
|
|
2719
2708
|
const isSList = this.isSectionList(sectionListColumns);
|
|
2709
|
+
this.rowsByKeys = {};
|
|
2720
2710
|
const sortingField = isNonNullString(this.sortRef.current.column) && isObj(this.state.columns) && this.state.columns[this.sortRef.current.column] || {};
|
|
2721
2711
|
const hasSortField = Object.size(sortingField,true);
|
|
2722
2712
|
if(this.canAutoSort() && isNonNullString(this.sortRef.current.column) && hasSortField){
|
|
@@ -2940,7 +2930,7 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
2940
2930
|
}
|
|
2941
2931
|
const isCollapsed = this.isSectionListCollapsed(key);
|
|
2942
2932
|
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]}>
|
|
2943
|
-
{false && <View testID={testID+"_LabelAndCollapsedContainer"} style={[theme.styles.w100,theme.styles.row,theme.styles.alignItemsCenter,theme.styles.
|
|
2933
|
+
{false && <View testID={testID+"_LabelAndCollapsedContainer"} style={[theme.styles.w100,theme.styles.row,theme.styles.alignItemsCenter,theme.styles.justifyContentFlexStart]}>
|
|
2944
2934
|
<Icon
|
|
2945
2935
|
name = {isCollapsed?"chevron-up":"chevron-right"}
|
|
2946
2936
|
color = {theme.colors.primaryOnSurface}
|
|
@@ -2960,9 +2950,9 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
2960
2950
|
if(isObj(rowKey)){
|
|
2961
2951
|
rowKey = this.getRowKey(rowKey,rowIndex);
|
|
2962
2952
|
}
|
|
2963
|
-
if(
|
|
2964
|
-
if(
|
|
2965
|
-
return !!this.selectedRowsRefs[rowKey].checked;
|
|
2953
|
+
if(typeof rowKey !=='string' && typeof rowKey !=='number') return false;
|
|
2954
|
+
if(!isObj(this.selectedRowsRefs[rowKey])) return false;
|
|
2955
|
+
return !!(isObj(this.selectedRows[rowKey]) && this.selectedRowsRefs[rowKey].checked);
|
|
2966
2956
|
}
|
|
2967
2957
|
/*** permet de définir les lignes sélectionnées du datagrid */
|
|
2968
2958
|
setSelectedRows (rows){
|
|
@@ -3152,20 +3142,18 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
3152
3142
|
}
|
|
3153
3143
|
return anchor(toggleItem)
|
|
3154
3144
|
}
|
|
3145
|
+
/**** cette fonction est appeléee lorsque la source de données change
|
|
3146
|
+
le composant dataSourceSelector doit retourner un table dataSelector, qui prendra en paramètre l'objet onChange, qui systématiquement doit être appelé lorsque la source de données change
|
|
3147
|
+
*/
|
|
3155
3148
|
onChangeDataSources(args){
|
|
3156
|
-
let {dataSources
|
|
3149
|
+
let {dataSources} = defaultObj(args);
|
|
3150
|
+
if(!Array.isArray(dataSources)) return;//la fonction onChangeDataSource doit retourner un dataSource de type array
|
|
3157
3151
|
if(this.props.onChangeDataSources =='function' && this.props.onChangeDataSources({dataSources,prev:this.currentDataSources}) === false) return;
|
|
3152
|
+
if(React.isEquals(this.previousDataSources,dataSources)) return;
|
|
3158
3153
|
this.currentDataSources = dataSources;
|
|
3159
3154
|
this.setSessionData({selectedDatabases:dataSources})
|
|
3160
|
-
|
|
3161
|
-
if(isObj(this.props.dataSourceSelectorProps) && isFunction(this.props.dataSourceSelectorProps.onChange)){
|
|
3162
|
-
args.datagridContext = this;
|
|
3163
|
-
this.props.dataSourceSelectorProps.onChange(args);
|
|
3164
|
-
}
|
|
3165
|
-
this.refresh(true);
|
|
3166
|
-
}
|
|
3155
|
+
this.refresh(true);
|
|
3167
3156
|
this.previousDataSources = dataSources;
|
|
3168
|
-
this.previousServer = server;
|
|
3169
3157
|
}
|
|
3170
3158
|
prepareFetchData(fetchData){
|
|
3171
3159
|
this.INITIAL_STATE.fetchData = defaultVal(fetchData,this.props.fetchData);
|
|
@@ -3368,17 +3356,20 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
3368
3356
|
fetchOptions.dataSources = this.currentDataSources;
|
|
3369
3357
|
fetchOptions.selector = fetchFilters;
|
|
3370
3358
|
fetchOptions.sort = this.getSort();
|
|
3371
|
-
const
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
fields =
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3359
|
+
const canIncludeField = typeof this.props.includeFieldsInFetchOptions =='boolean'? this.props.includeFieldsInFetchOptions : defaultBool(appConfig.get("includeFieldsInDatagridFetchOptions"),appConfig.includeFieldsInDatagridFetchOptions) !== false;
|
|
3360
|
+
if(canIncludeField){
|
|
3361
|
+
const ff = this.getFilterableColumnsNames();
|
|
3362
|
+
let fields = ff;
|
|
3363
|
+
if(this.isFetchOnlyVisibleColumnsEnabled()){
|
|
3364
|
+
fields = [];
|
|
3365
|
+
Object.map(ff,(field)=>{
|
|
3366
|
+
if(isNonNullString(field) && isObj(this.state.columns[field]) && this.state.columns[field].visible !== false){
|
|
3367
|
+
fields.push(field);
|
|
3368
|
+
}
|
|
3369
|
+
});
|
|
3370
|
+
}
|
|
3371
|
+
fetchOptions.fields = fields;
|
|
3380
3372
|
}
|
|
3381
|
-
fetchOptions.fields = fields;
|
|
3382
3373
|
let limit = this.getQueryLimit();
|
|
3383
3374
|
if(limit > 0 && !this.isPivotDatagrid()){
|
|
3384
3375
|
fetchOptions.limit = limit;
|
|
@@ -3742,6 +3733,9 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
3742
3733
|
renderSelectFieldCell(args){
|
|
3743
3734
|
return this.renderSelectFieldCell(args);
|
|
3744
3735
|
}
|
|
3736
|
+
getRowByKey(rowKey){
|
|
3737
|
+
return this.rowsByKeys[rowKey] || null;
|
|
3738
|
+
}
|
|
3745
3739
|
/*** retourne le rendu d'une cellule de la ligne du tableau
|
|
3746
3740
|
@parm, rowData, object, la ligne à afficher le rendu du contenu
|
|
3747
3741
|
@param , rowInidex, l'indice de la ligne dont on affiche le rendu en cours
|
|
@@ -3759,10 +3753,11 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
3759
3753
|
const renderText = isSectionListHeader === true || customRenderRowCell === false ? true : false;
|
|
3760
3754
|
if(!isObj(rowData)) return renderText ? null : {render:null,extra:{}};
|
|
3761
3755
|
rowIndex = isDecimal(rowIndex)? rowIndex : isDecimal(index)? index : undefined;
|
|
3756
|
+
rowKey = rowKey || typeof rowKey =='number' ? rowKey : this.getRowKey(rowData,rowIndex);
|
|
3757
|
+
this.rowsByKeys[rowKey] = rowData;
|
|
3762
3758
|
rowCounterIndex = isDecimal(rowCounterIndex) ? rowCounterIndex : isDecimal(rowIndex)? rowIndex+1 : defaultDecimal(rowCounterIndex);
|
|
3763
3759
|
if(this.isSelectableColumn(columnDef,columnField)){
|
|
3764
3760
|
if(renderText) return null;
|
|
3765
|
-
rowKey = rowKey ? rowKey : this.getRowKey(rowData,rowIndex);
|
|
3766
3761
|
return {render :handleSelectableColumn === false ? null : this.renderSelectableCheckboxCell({
|
|
3767
3762
|
...arg,
|
|
3768
3763
|
rowKey,
|
|
@@ -3770,7 +3765,7 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
3770
3765
|
checked : this.isRowSelected(rowKey,rowIndex),
|
|
3771
3766
|
rowsRefs : this.selectedRowsRefs,
|
|
3772
3767
|
onPress : ({checked})=>{
|
|
3773
|
-
return this.handleRowToggle({
|
|
3768
|
+
return this.handleRowToggle({rowIndex,rowKey,selected:!checked});
|
|
3774
3769
|
}
|
|
3775
3770
|
}),style:{},extra:{style:{}}};
|
|
3776
3771
|
} else if((columnField == this.getIndexColumnName())){
|
|
@@ -3812,6 +3807,7 @@ CommonDatagridComponent.propTypes = {
|
|
|
3812
3807
|
PropTypes.node,
|
|
3813
3808
|
PropTypes.element,
|
|
3814
3809
|
]),
|
|
3810
|
+
includeFieldsInFetchOptions : PropTypes.bool,//si les champs de colonnes seront inclus dans les fetchOptions du datagrid
|
|
3815
3811
|
canMakePhoneCall : PropTypes.bool,//si l'on peut faire un appel sur la données sélectionnées
|
|
3816
3812
|
makePhoneCallProps : PropTypes.oneOfType([
|
|
3817
3813
|
PropTypes.object,
|
|
@@ -80,7 +80,8 @@ export default class DatagridDashboard extends TableData {
|
|
|
80
80
|
autoSort,
|
|
81
81
|
exportable,
|
|
82
82
|
selectable,pagin,showPagination,
|
|
83
|
-
sessionName,onMount,onUnmount,onFetchData,dataSourceSelector,
|
|
83
|
+
sessionName,onMount,onUnmount,onFetchData,dataSourceSelector,
|
|
84
|
+
queryLimit,
|
|
84
85
|
filters,
|
|
85
86
|
filterOrOperator,
|
|
86
87
|
filterAndOperator,
|
|
@@ -115,7 +115,8 @@ const DatagridFactory = (Factory)=>{
|
|
|
115
115
|
autoSort,
|
|
116
116
|
exportable,
|
|
117
117
|
selectable,pagin,showPagination,
|
|
118
|
-
sessionName,onMount,onUnmount,onFetchData,dataSourceSelector,
|
|
118
|
+
sessionName,onMount,onUnmount,onFetchData,dataSourceSelector,
|
|
119
|
+
queryLimit,
|
|
119
120
|
filters,
|
|
120
121
|
chartContainerProps,
|
|
121
122
|
accordion, //pour le rendu du header en accordion
|
|
@@ -125,22 +126,6 @@ const DatagridFactory = (Factory)=>{
|
|
|
125
126
|
chartContainerProps = defaultObj(chartContainerProps);
|
|
126
127
|
testID = this.getTestID();
|
|
127
128
|
rest = defaultObj(rest);
|
|
128
|
-
if(dataSourceSelector === true){
|
|
129
|
-
showDataSourceSelector = true;
|
|
130
|
-
} else if(dataSourceSelector ===false){
|
|
131
|
-
showDataSourceSelector = false;
|
|
132
|
-
}
|
|
133
|
-
dataSourceSelectorProps = defaultObj(dataSourceSelectorProps);
|
|
134
|
-
let _dataSourceSelector = undefined;/* showDataSourceSelector ? <div>
|
|
135
|
-
<DBSelector
|
|
136
|
-
{...dataSourceSelectorProps}
|
|
137
|
-
onChange = {this.onChangeDatabases.bind(this)}
|
|
138
|
-
/>
|
|
139
|
-
</div> : null;*/
|
|
140
|
-
if(!title){
|
|
141
|
-
title = _dataSourceSelector;
|
|
142
|
-
_dataSourceSelector = null;
|
|
143
|
-
}
|
|
144
129
|
exportable = defaultBool(exportable,true);
|
|
145
130
|
let isMobile = isMobileOrTabletMedia();
|
|
146
131
|
selectable = defaultVal(selectable,true);
|
|
@@ -295,7 +280,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
295
280
|
<View ref={this.layoutRef} testID={testID+"_LayoutContainer"}>
|
|
296
281
|
{this.props.showActions !== false ? <DatagridActions
|
|
297
282
|
pointerEvents = {pointerEvents}
|
|
298
|
-
title = {
|
|
283
|
+
title = {this.renderDataSourceSelector()}
|
|
299
284
|
context = {this}
|
|
300
285
|
selectedRows = {Object.assign({},this.selectedRows)}
|
|
301
286
|
selectedRowsActions = {this.renderSelectedRowsActions.bind(this)}
|
|
@@ -397,7 +397,7 @@ export default class Field extends AppComponent {
|
|
|
397
397
|
getValidValue (data){
|
|
398
398
|
let v = this.state.validValue;
|
|
399
399
|
if(isFunction(this.props.getValidValue)){
|
|
400
|
-
let v1 = this.props.getValidValue.call(this,{data,context:this,props:this.props});
|
|
400
|
+
let v1 = this.props.getValidValue.call(this,{data,context:this,value:v,validValue:v,state:this.state,props:this.props});
|
|
401
401
|
if(v1 !== undefined){
|
|
402
402
|
v = v1;
|
|
403
403
|
}
|
|
@@ -55,7 +55,6 @@ export default class FormIDField extends TextField {
|
|
|
55
55
|
/*** retourne la valeur validée */
|
|
56
56
|
getValidValue(data){
|
|
57
57
|
const validValue = super.getValidValue(data);
|
|
58
|
-
console.log(data, " is valid value ",data);
|
|
59
58
|
if(!isNonNullString(this.name)) return validValue;
|
|
60
59
|
data[this.name] = defaultStr(data[this.name],validValue,this.newFieldIdValue);
|
|
61
60
|
return validValue;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// license that can be found in the LICENSE file.
|
|
4
4
|
|
|
5
5
|
import Dropdown from "$ecomponents/Dropdown";
|
|
6
|
-
import {defaultStr,isFunction,defaultVal,isObjOrArray,defaultObj} from "$cutils";
|
|
6
|
+
import {defaultStr,extendObj,isFunction,defaultVal,isObjOrArray,defaultObj} from "$cutils";
|
|
7
7
|
import PropTypes from "prop-types";
|
|
8
8
|
import actions from "$cactions";
|
|
9
9
|
import {navigateToTableData} from "$enavigation/utils";
|
|
@@ -19,7 +19,7 @@ import appConfig from "$appConfig";
|
|
|
19
19
|
* foreignKeyTable : la tableData dans laquelle effectuer les donées de la requêtes
|
|
20
20
|
* foreignKeyLabel : Le libélé dans la table étrangère
|
|
21
21
|
*/
|
|
22
|
-
const TableDataSelectField = React.forwardRef(({foreignKeyColumn,bindUpsert2RemoveEvents,onAdd,showAdd:customShowAdd,canShowAdd,foreignKeyTable,fetchItemsPath,foreignKeyLabel,foreignKeyLabelIndex,dropdownActions,fields,fetchItems:customFetchItem,convertFiltersToSQL,mutateFetchedItems,getForeignKeyTable,onFetchItems,isFilter,isUpdate,isDocEditing,items,onAddProps,fetchOptions,...props},ref)=>{
|
|
22
|
+
const TableDataSelectField = React.forwardRef(({foreignKeyColumn,prepareFilters:cPrepareFilters,bindUpsert2RemoveEvents,onAdd,showAdd:customShowAdd,canShowAdd,foreignKeyTable,fetchItemsPath,foreignKeyLabel,foreignKeyLabelIndex,dropdownActions,fields,fetchItems:customFetchItem,convertFiltersToSQL,mutateFetchedItems,getForeignKeyTable,onFetchItems,isFilter,isUpdate,isDocEditing,items,onAddProps,fetchOptions,...props},ref)=>{
|
|
23
23
|
props.data = defaultObj(props.data);
|
|
24
24
|
if(!foreignKeyColumn && isNonNullString(props.field)){
|
|
25
25
|
foreignKeyColumn = props.field;
|
|
@@ -138,8 +138,12 @@ const TableDataSelectField = React.forwardRef(({foreignKeyColumn,bindUpsert2Remo
|
|
|
138
138
|
if(!isMounted()) return;
|
|
139
139
|
if(typeof beforeFetchItems ==='function' && beforeFetchItems(fetchOptions) === false) return;
|
|
140
140
|
let opts = Object.clone(fetchOptions);
|
|
141
|
-
|
|
142
|
-
|
|
141
|
+
if(cPrepareFilters !== false){
|
|
142
|
+
opts.selector = prepareFilters(fetchOptions.selector,{convertToSQL:convertFiltersToSQL});
|
|
143
|
+
opts = getFetchOptions(opts);
|
|
144
|
+
} else {
|
|
145
|
+
opts = {fetchOptions};
|
|
146
|
+
}
|
|
143
147
|
const r = fetchItems(opts);
|
|
144
148
|
if(r === false) return;
|
|
145
149
|
setIsLoading(true);
|
|
@@ -296,6 +300,7 @@ const TableDataSelectField = React.forwardRef(({foreignKeyColumn,bindUpsert2Remo
|
|
|
296
300
|
|
|
297
301
|
TableDataSelectField.propTypes = {
|
|
298
302
|
...Dropdown.propTypes,
|
|
303
|
+
prepareFilters : PropTypes.bool,//si les filtres seront customisé
|
|
299
304
|
bindUpsert2RemoveEvents : PropTypes.bool,//si le composant écoutera l'évènement de rafraichissement des données
|
|
300
305
|
onAdd : PropTypes.func, //({})=>, la fonction appelée lorsque l'on clique sur le bouton add
|
|
301
306
|
canShowAdd : PropTypes.func, //({foreignKeyTable,foreignKeyColumn})=><boolean> la fonction permettant de spécifier si l'on peut afficher le bouton showAdd
|
|
@@ -312,7 +312,7 @@ const SimpleSelect = React.forwardRef((props,ref)=>{
|
|
|
312
312
|
style = {[{marginTop}]}
|
|
313
313
|
anchor = {anchor}
|
|
314
314
|
contentProps = {{style:{flex:1}}}
|
|
315
|
-
minWidth = {
|
|
315
|
+
minWidth = {180}
|
|
316
316
|
contentStyle = {[{paddingVertical:0},rProps.contentStyle]}
|
|
317
317
|
>
|
|
318
318
|
<View
|
|
@@ -322,7 +322,7 @@ const SimpleSelect = React.forwardRef((props,ref)=>{
|
|
|
322
322
|
paddingHorizontal : 10,
|
|
323
323
|
paddingVertical:0,
|
|
324
324
|
height : !isMob?contentContainerHeight:'90%',
|
|
325
|
-
width : !isMob ? Math.max(layout.width,
|
|
325
|
+
width : !isMob ? Math.max(layout.width,180) : undefined,
|
|
326
326
|
},
|
|
327
327
|
isMob && {flex:1},
|
|
328
328
|
!isMob && {paddingRight : 0},
|
|
@@ -53,14 +53,17 @@ export default class FormDataLayout extends FormDataActions {
|
|
|
53
53
|
close(){
|
|
54
54
|
return goBack(true);
|
|
55
55
|
}
|
|
56
|
+
isLoading(){
|
|
57
|
+
return !!(this.props.isLoading)
|
|
58
|
+
}
|
|
56
59
|
wrapRenderingContent(content,wProps){
|
|
57
60
|
let {
|
|
58
61
|
withHeavyScreen,
|
|
59
62
|
preloader,
|
|
60
63
|
preloaderProps,
|
|
61
64
|
testID,
|
|
62
|
-
isLoading,
|
|
63
65
|
} = this.props;
|
|
66
|
+
const isLoading = this.isLoading();
|
|
64
67
|
wProps = defaultObj(wProps);
|
|
65
68
|
const useHeavyScreen = withHeavyScreen !== false || isLoading == true? true : false;
|
|
66
69
|
const Wrapper = useHeavyScreen ? HeavyScreen : React.Fragment;
|
|
@@ -20,7 +20,7 @@ import {renderTabsContent,renderActions} from "./utils";
|
|
|
20
20
|
import theme from "$theme";
|
|
21
21
|
import cActions from "$cactions";
|
|
22
22
|
import APP from "$capp/instance";
|
|
23
|
-
import { generatedColumnsProperties } from "./utils";
|
|
23
|
+
import { generatedColumnsProperties,defaultArchivedPermsFilter } from "./utils";
|
|
24
24
|
import {isDocEditing,checkPrimaryKey} from "$ecomponents/Form";
|
|
25
25
|
import i18n from "$i18n";
|
|
26
26
|
import fetch from "$capi/fetch";
|
|
@@ -55,7 +55,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
55
55
|
if(r === false || (!args.value && typeof args.value != 'number')) return r;
|
|
56
56
|
//on applique la validation seulement en cas de non mise à jour
|
|
57
57
|
if(!this.isCurrentDocEditingUpdate() && context && typeof context.onNoValidate =='function'){
|
|
58
|
-
const cb = typeof field.fetchUniqueId =='function'? field.fetchUniqueId : typeof this.fetchUniqueId =='function'? this.fetchUniqueId : undefined;
|
|
58
|
+
const cb = typeof field.fetchUniqueId =='function'? field.fetchUniqueId : typeof this.props.fetchUniqueId =='function'? this.props.fetchUniqueId : undefined;
|
|
59
59
|
if(cb){
|
|
60
60
|
const r2 = cb(args);
|
|
61
61
|
if(isPromise(r2)){
|
|
@@ -93,21 +93,11 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
93
93
|
tableName : { value : defaultStr(table.table,table.tableName)},
|
|
94
94
|
fields : {value : fields},
|
|
95
95
|
table : {value : table},
|
|
96
|
+
archivedPermsFilterFunc : {value : typeof mainProps.archivedPermsFilter =='function'? mainProps.archivedPermsFilter:defaultArchivedPermsFilter},
|
|
96
97
|
isDocEditingRef : {value : {current:false}},
|
|
97
|
-
validateDataBeforeSave : {value : mainProps.validateData},
|
|
98
|
-
upsertDataToDB : {value : mainProps.upsertToDB},
|
|
99
|
-
makePhoneCallProps : {value : mainProps.makePhoneCallProps},
|
|
100
|
-
onSaveProp : {value : mainProps.onSave},
|
|
101
|
-
titleProp : {value : mainProps.title},
|
|
102
98
|
closeOnSaveProp : {value : mainProps.closeOnSave || mainProps.closeAfterSave },
|
|
103
|
-
newActionProp : {value : mainProps.newAction},
|
|
104
|
-
fetchUniqueId : {value : mainProps.fetchUniqueId},
|
|
105
99
|
//la liste des champ de type clé primaire associés à la table
|
|
106
100
|
primaryKeyFields : {value : primaryKeyFields},
|
|
107
|
-
cloneProp : {value : typeof mainProps.clone =='function' && mainProps.clone || undefined},
|
|
108
|
-
printProp : {value : typeof mainProps.print =='function' && mainProps.print || undefined},
|
|
109
|
-
archiveProp : {value : typeof mainProps.archive =='function' && mainProps.archive || undefined },
|
|
110
|
-
testIDProp : {value : defaultStr(mainProps.testID)},
|
|
111
101
|
showPreloaderOnUpsert : {value : mainProps.showPreloaderOnUpsert},
|
|
112
102
|
});
|
|
113
103
|
this.hidePreloader = this.hidePreloader.bind(this);
|
|
@@ -145,7 +135,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
145
135
|
return defaultObj(this.state.data);
|
|
146
136
|
}
|
|
147
137
|
/**** retourne les props en cours d'édition */
|
|
148
|
-
|
|
138
|
+
getCurrentRenderingProps (){
|
|
149
139
|
return defaultObj(this.currentRenderingProps);
|
|
150
140
|
}
|
|
151
141
|
/* Attention, cette méthode est appélée dans la méthode getComponentProps de la classe parente.
|
|
@@ -165,15 +155,44 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
165
155
|
* datas: la liste des données passées à la TableData
|
|
166
156
|
* }
|
|
167
157
|
*/
|
|
168
|
-
getActionsPerms(
|
|
169
|
-
|
|
158
|
+
getActionsPerms(args){
|
|
159
|
+
const eProps = this.getCurrentRenderingProps();
|
|
160
|
+
const gPA = typeof eProps.getActionsPerms =='function'? eProps.getActionsPerms : typeof this.props.getActionsPerms =='function'? this.props.getActionsPerms : undefined;
|
|
161
|
+
const permsR = gPA ? gPA.call(this,args) : null;
|
|
162
|
+
const {perm,action,tableName} = args;
|
|
163
|
+
const ePerms = (isNonNullString(perm)? Auth.isAllowed({resource:perm.split(':')[0],action}):Auth.isTableDataAllowed({table:tableName,action}));
|
|
164
|
+
return isObj(permsR) ? extendObj({},ePerms,permsR) : ePerms;
|
|
170
165
|
}
|
|
171
166
|
getRenderedActionPrefix (){}
|
|
172
167
|
renderActions(){
|
|
173
168
|
return null;
|
|
174
169
|
}
|
|
170
|
+
isLoading(){
|
|
171
|
+
return !!(this.getCurrentRenderingProps().isLoading) || !!this.props.isLoading;
|
|
172
|
+
}
|
|
173
|
+
/**** permet de preparer les composant props
|
|
174
|
+
si la fonction retourne un élément react, alors l'élément react est rendu comme résultat du composant
|
|
175
|
+
*/
|
|
176
|
+
prepareComponentProps(props){
|
|
177
|
+
const obj = typeof this.props.prepareComponentProps =='function'? this.props.prepareComponentProps(props) : null;
|
|
178
|
+
if(isObj(obj)){
|
|
179
|
+
return extendObj({},props,obj);
|
|
180
|
+
}
|
|
181
|
+
return props;
|
|
182
|
+
}
|
|
175
183
|
getComponentProps(props){
|
|
176
184
|
this.resetState();
|
|
185
|
+
const table = this.table;
|
|
186
|
+
const {datas,currentIndex,data} = this.state;
|
|
187
|
+
const tableName = this.tableName;
|
|
188
|
+
const isUpdated = this.isDocEditing(data);
|
|
189
|
+
this.isDocEditingRef.current = !!isUpdated;
|
|
190
|
+
const isMobOrTab = isMobileOrTabletMedia();
|
|
191
|
+
let archived = this.isArchived();
|
|
192
|
+
this.INITIAL_STATE.archived = archived;
|
|
193
|
+
this.INITIAL_STATE.tableName = tableName;
|
|
194
|
+
const fields = {};
|
|
195
|
+
const fieldsToPrepare = extendObj({},true,this.fields,customFields);
|
|
177
196
|
const {
|
|
178
197
|
actions,
|
|
179
198
|
fields:customFields,
|
|
@@ -202,20 +221,10 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
202
221
|
formProps : customFormProps,
|
|
203
222
|
newElementLabel,
|
|
204
223
|
prepareField,
|
|
224
|
+
prepareComponentProps,
|
|
205
225
|
...rest
|
|
206
|
-
} = props;
|
|
207
|
-
const table = this.table;
|
|
208
|
-
const {datas,currentIndex,data} = this.state;
|
|
209
|
-
const tableName = this.tableName;
|
|
226
|
+
} = this.prepareComponentProps({...props,tableName,fields:fieldsToPrepare,isUpdated,isUpdate:isUpdated,data,datas,currentIndex});
|
|
210
227
|
const sessionName = this.INITIAL_STATE.sessionName = defaultStr(customSessionName,"table-form-data"+tableName);
|
|
211
|
-
const isUpdated = this.isDocEditing(data);
|
|
212
|
-
this.isDocEditingRef.current = !!isUpdated;
|
|
213
|
-
const isMobOrTab = isMobileOrTabletMedia();
|
|
214
|
-
let archived = this.isArchived();
|
|
215
|
-
this.INITIAL_STATE.archived = archived;
|
|
216
|
-
this.INITIAL_STATE.tableName = tableName;
|
|
217
|
-
const fields = {};
|
|
218
|
-
const fieldsToPrepare = extendObj({},true,this.fields,customFields);
|
|
219
228
|
const prepareCb = typeof prepareField =='function'? prepareField : x=> x;
|
|
220
229
|
///on effectue une mutator sur le champ en cours de modification
|
|
221
230
|
Object.map(fieldsToPrepare,(field,i,counterIndex)=>{
|
|
@@ -287,11 +296,11 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
287
296
|
sessionName,
|
|
288
297
|
table,
|
|
289
298
|
newElementLabel : this.getNewElementLabel(),
|
|
290
|
-
printable : this.isPrintable(),///si la table data est imprimable,
|
|
299
|
+
printable : (typeof rest.printable ==='boolean' ? rest.printable : true) && this.isPrintable(),///si la table data est imprimable,
|
|
291
300
|
canMakePhoneCall : this.canMakePhoneCall(),
|
|
292
301
|
makePhoneCallProps:this.getMakePhoneCallProps(),
|
|
293
302
|
onPressToMakePhoneCall : this.makePhoneCall.bind(this),
|
|
294
|
-
archivable : this.isArchivable(),
|
|
303
|
+
archivable : (typeof rest.archivable ==='boolean' ? rest.archivable : true) && this.isArchivable(),
|
|
295
304
|
saveButton : isUpdated?'Modifier':'Enregistrer',
|
|
296
305
|
currentData:data,
|
|
297
306
|
hasManyData : this.hasManyData(),
|
|
@@ -355,10 +364,10 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
355
364
|
return rActionsArg;
|
|
356
365
|
}
|
|
357
366
|
_render ({header,content,context}){
|
|
358
|
-
const restProps = this.
|
|
367
|
+
const restProps = this.getCurrentRenderingProps();
|
|
359
368
|
delete restProps.tabs;
|
|
360
369
|
let {tabProps,firstTabProps,tabsProps,withScrollView} = restProps;
|
|
361
|
-
let testID = this.
|
|
370
|
+
let testID = this.props.testID;
|
|
362
371
|
tabsProps = defaultObj(tabsProps);
|
|
363
372
|
tabsProps.tabContentProps = defaultObj(tabsProps.tabContentProps);
|
|
364
373
|
tabsProps.tabContentProps.stopChildrenEventPropagation = typeof tabsProps.tabContentProps.stopChildrenEventPropagation =="function" ? tabsProps.tabContentProps.stopChildrenEventPropagation : false;
|
|
@@ -438,7 +447,9 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
438
447
|
return this.state.currentIndex;
|
|
439
448
|
}
|
|
440
449
|
isArchivable(){
|
|
441
|
-
|
|
450
|
+
const editingProps = this.getCurrentRenderingProps();
|
|
451
|
+
if(typeof editingProps.archivable =='boolean') return editingProps.archivable;
|
|
452
|
+
return !!this.props.archivable;
|
|
442
453
|
}
|
|
443
454
|
isArchived(data){
|
|
444
455
|
data = defaultObj(data,this.state.data);
|
|
@@ -491,7 +502,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
491
502
|
return true;
|
|
492
503
|
}
|
|
493
504
|
isPrintable(){
|
|
494
|
-
return
|
|
505
|
+
return !!(this.props.printable);
|
|
495
506
|
}
|
|
496
507
|
/*** retourne la liste des valeurs de clé primarire associés à la table data pour la données en cours de modification
|
|
497
508
|
* Elle permet d'afficher dans la barre de titre, les identifiants de la table de données en cours de modification
|
|
@@ -519,17 +530,17 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
519
530
|
return super.isDocEditing(data);
|
|
520
531
|
}
|
|
521
532
|
print(data){
|
|
522
|
-
if(!this.isPrintable() && typeof this.
|
|
533
|
+
if(!this.isPrintable() && typeof this.props.print !=='function') return;
|
|
523
534
|
data = this.isDocEditing(data)? data : isObj(data) && this.isDocEditing(data.data)? data.data : {};
|
|
524
|
-
return this.
|
|
535
|
+
return this.props.print(data,this);
|
|
525
536
|
}
|
|
526
537
|
isClonable(){
|
|
527
|
-
return
|
|
538
|
+
return !!(this.props.clonable !==false);
|
|
528
539
|
}
|
|
529
540
|
clone (data){
|
|
530
541
|
if(!this._isMounted() || !this.isClonable())return data;
|
|
531
542
|
data = {...this.getCurrentEditingData(data)};
|
|
532
|
-
if(this.
|
|
543
|
+
if(typeof this.props.clone ==='function' && this.props.clone(data,this) === false) return data;
|
|
533
544
|
this.showPreloader();
|
|
534
545
|
delete data.approved;
|
|
535
546
|
Object.map(['_rev',...generatedColumnsProperties,...Object.keys(this.primaryKeyFields),'_id','code','updateBy','updatedDate','createBy','updatedHour','createdHour','createdDate'],(idx)=>{
|
|
@@ -580,8 +591,8 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
580
591
|
return true;
|
|
581
592
|
}
|
|
582
593
|
upsertToDB(args){
|
|
583
|
-
if(typeof this.
|
|
584
|
-
return this.
|
|
594
|
+
if(typeof this.props.upsertToDB ==='function'){
|
|
595
|
+
return this.props.upsertToDB(args);
|
|
585
596
|
}
|
|
586
597
|
return Promise.resolve({});
|
|
587
598
|
}
|
|
@@ -596,15 +607,19 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
596
607
|
return this.doSave(args);
|
|
597
608
|
}
|
|
598
609
|
canCreateNew(){
|
|
599
|
-
|
|
610
|
+
const editingProps = this.getCurrentRenderingProps();
|
|
611
|
+
if("newAction" in editingProps){
|
|
612
|
+
return !!editingProps.newAction;
|
|
613
|
+
}
|
|
614
|
+
return this.props.newAction !== false ? true : false;
|
|
600
615
|
}
|
|
601
616
|
createNew(){
|
|
602
617
|
return this.reset();
|
|
603
618
|
}
|
|
604
619
|
archive(){}
|
|
605
620
|
validateData(args){
|
|
606
|
-
if(typeof this.
|
|
607
|
-
return this.
|
|
621
|
+
if(typeof this.props.validateData =='function'){
|
|
622
|
+
return this.props.validateData(args);
|
|
608
623
|
}
|
|
609
624
|
return true;
|
|
610
625
|
}
|
|
@@ -659,7 +674,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
659
674
|
let savedData = this.isDocEditing(upserted)? upserted : data;
|
|
660
675
|
const newArgs = {tableName,actionName:action,action,table:this.table,data:savedData,result:upserted,context};
|
|
661
676
|
APP.trigger(cActions.upsert(tableName),newArgs);
|
|
662
|
-
if(this.onSaveTableData(newArgs) === false || (isFunction(this.
|
|
677
|
+
if(this.onSaveTableData(newArgs) === false || (isFunction(this.props.onSave)&& this.props.onSave(newArgs) === false)){
|
|
663
678
|
closePreloader();
|
|
664
679
|
return;
|
|
665
680
|
}
|
|
@@ -754,7 +769,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
754
769
|
}
|
|
755
770
|
getMakePhoneCallProps (){
|
|
756
771
|
const table = this.table;
|
|
757
|
-
const makePhoneCallProps = defaultVal(this.makePhoneCallProps,table.makePhoneCallProps);
|
|
772
|
+
const makePhoneCallProps = defaultVal(this.props.makePhoneCallProps,table.makePhoneCallProps);
|
|
758
773
|
const rowData = this.getCurrentData();
|
|
759
774
|
const mP = typeof makePhoneCallProps === 'function' ? makePhoneCallProps({rowData,data:rowData,isTableData:true,props:this.props,context:this,table,tableName:this.table}) : makePhoneCallProps;
|
|
760
775
|
return mP !== false ? defaultObj(mP) : null;
|
|
@@ -769,8 +784,8 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
769
784
|
/*** archivedPermsFilter est la fonction permettant de filtres les permissions qui par défaut ne figurent pas parmis les permissions en readOnly
|
|
770
785
|
* si archivedPermFilter retourne true pour une permission données alors cette permission sera ignorée
|
|
771
786
|
*/
|
|
772
|
-
archivedPermsFilter (
|
|
773
|
-
return
|
|
787
|
+
archivedPermsFilter (...args){
|
|
788
|
+
return !!this.archivedPermsFilterFunc(...args);
|
|
774
789
|
};
|
|
775
790
|
copyToClipboard(){
|
|
776
791
|
return copyToClipboard({
|
|
@@ -794,7 +809,8 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
794
809
|
return ret;
|
|
795
810
|
}
|
|
796
811
|
getAppBarTitle (){
|
|
797
|
-
|
|
812
|
+
const editingProps = this.getCurrentRenderingProps();
|
|
813
|
+
return React.isValidElement(editingProps.title,true) && editingProps.title || React.isValidElement(this.props.title,true) && this.props.title || this.table.text || this.table.label || null;
|
|
798
814
|
}
|
|
799
815
|
getAppBarProps(a){
|
|
800
816
|
const r = super.getAppBarProps(a);
|
|
@@ -811,6 +827,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
|
|
|
811
827
|
|
|
812
828
|
TableDataScreenComponent.propTypes = {
|
|
813
829
|
...defaultObj(FormData.propTypes),
|
|
830
|
+
prepareComponentProps : PropTypes.func, //permet d'appreter les components props à utiliser pour le rendu des données
|
|
814
831
|
prepareField : PropTypes.func,//La fonction permettant de faire des mutations sur le champ field à passer au formulaire form. si elle retourne false alors la field ne sera pas pris een compte
|
|
815
832
|
table : PropTypes.shape({
|
|
816
833
|
tableName : PropTypes.string,
|
|
@@ -820,7 +837,7 @@ TableDataScreenComponent.propTypes = {
|
|
|
820
837
|
unique : PropTypes.bool,//si la validation de type unique sur le champ sera effective
|
|
821
838
|
fetchUniqueId : PropTypes.func,//la fonction permettant de fetch un élément unique pour la validation de type uniqueID, liée aux champs de type piece et id
|
|
822
839
|
validateData : PropTypes.func,// la fonction permettant de valider les données à enregistrer
|
|
823
|
-
archivedPermsFilter : PropTypes.func,///le filtre des permissions archivées
|
|
840
|
+
archivedPermsFilter : PropTypes.func,///le filtre des permissions archivées, elle permet de laisser uniquement les permissions de faire un filtre sur les permission et ne laisser que celle qui sont considérées comme disposible en cas de document archivé
|
|
824
841
|
newElementLabel : PropTypes.string,//le titre du bouton nouveau pour l'ajout d'un nouvel élément
|
|
825
842
|
customActionKeyPrefix : PropTypes.oneOfType([
|
|
826
843
|
PropTypes.string,
|
|
@@ -71,11 +71,10 @@ export const renderTabsContent = ({tabs,context,data,sessionName,tabsPropsMutato
|
|
|
71
71
|
}
|
|
72
72
|
return null;
|
|
73
73
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
export function renderActions({context,isUpdate,newElementLabel,makePhoneCallProps,hasManyData,onPressCopyToClipboard,archived,archivedPermsFilter,canMakePhoneCall,onPressToMakePhoneCall,saveAction,save2newAction,save2closeAction,cloneAction,readOnly,printable,archivable,data,table,perm,tableName,saveButton,datas,rows,currentData,currentDataIndex,onPressToSave,onPressToCreateNew,onPressToPrint,onPressToPrevious,onPressToNext,onPressToArchive,...rest}){
|
|
74
|
+
export const readablePerms = ["read","print"];
|
|
75
|
+
export const defaultArchivedPermsFilter = ({perm})=>!readablePerms.includes(perm) && !readablePerms.includes(perm.toLowerCase());
|
|
76
|
+
export function renderActions({context,isUpdate,newElementLabel,readablePerms:cReadablePerms,makePhoneCallProps,hasManyData,onPressCopyToClipboard,archived,archivedPermsFilter,canMakePhoneCall,onPressToMakePhoneCall,saveAction,save2newAction,save2closeAction,cloneAction,readOnly,printable,archivable,data,table,perm,tableName,saveButton,datas,rows,currentData,currentDataIndex,onPressToSave,onPressToCreateNew,onPressToPrint,onPressToPrevious,onPressToNext,onPressToArchive,...rest}){
|
|
77
77
|
let textSave = defaultStr(saveButton)
|
|
78
|
-
archivedPermsFilter = defaultFunc(archivedPermsFilter,x=>true);
|
|
79
78
|
table = defaultStr(tableName,table);
|
|
80
79
|
datas = defaultArray(datas,rows);
|
|
81
80
|
const self = context || {}
|
|
@@ -83,9 +82,10 @@ export function renderActions({context,isUpdate,newElementLabel,makePhoneCallPr
|
|
|
83
82
|
const getActionsPerms = isFunction(self.getActionsPerms) ? self.getActionsPerms.bind(self) : undefined;
|
|
84
83
|
let perms = {};
|
|
85
84
|
readOnly = defaultBool(readOnly,false);
|
|
85
|
+
const callArgs = {readOnly,perm,archived,isUpdate,currentData,action,data,tableName:table,table,context,datas};
|
|
86
86
|
if(getActionsPerms){
|
|
87
87
|
/**** getAction perms est la fonction appelée parl'objet TableData, pour retourner les permission des actions de la tableData */
|
|
88
|
-
perms = getActionsPerms.call(self,
|
|
88
|
+
perms = getActionsPerms.call(self,callArgs)
|
|
89
89
|
} else {
|
|
90
90
|
perms = (isNonNullString(perm)? Auth.isAllowed({resource:perm.split(':')[0],action}):Auth.isTableDataAllowed({table,action}));
|
|
91
91
|
}
|
|
@@ -97,8 +97,11 @@ export function renderActions({context,isUpdate,newElementLabel,makePhoneCallPr
|
|
|
97
97
|
delete perms.archive;
|
|
98
98
|
delete perms.archivable;
|
|
99
99
|
}
|
|
100
|
-
if(
|
|
101
|
-
|
|
100
|
+
if(archived){
|
|
101
|
+
archivedPermsFilter = defaultFunc(archivedPermsFilter,defaultArchivedPermsFilter);
|
|
102
|
+
Object.map(perms,(p,perm)=>{
|
|
103
|
+
if(archivedPermsFilter({perm,perms,data,tableName,readOnly,currentData,context,tableName,isUpdate})) delete perms[i];
|
|
104
|
+
});
|
|
102
105
|
}
|
|
103
106
|
rest = defaultObj(rest);
|
|
104
107
|
newElementLabel = defaultStr(newElementLabel,"Nouveau");
|
|
File without changes
|