@fto-consult/expo-ui 2.36.5 → 2.37.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/package.json +3 -2
- package/src/components/Datagrid/Accordion/index.js +1 -19
- package/src/components/Datagrid/Common/Common.js +203 -3
- package/src/components/Datagrid/Common/utils.js +11 -5
- package/src/components/Datagrid/Table/index.js +1 -0
- package/src/components/Dialog/Provider.js +1 -1
- package/src/components/Form/FormData/DialogProvider.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fto-consult/expo-ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.37.0",
|
|
4
4
|
"description": "Bibliothèque de composants UI Expo,react-native",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"@emotion/native": "^11.10.0",
|
|
62
62
|
"@expo/html-elements": "^0.2.0",
|
|
63
63
|
"@expo/vector-icons": "^13.0.0",
|
|
64
|
-
"@fto-consult/common": "^2.1.
|
|
64
|
+
"@fto-consult/common": "^2.1.4",
|
|
65
65
|
"@gorhom/portal": "^1.0.14",
|
|
66
66
|
"@react-native-async-storage/async-storage": "~1.17.3",
|
|
67
67
|
"@react-native-community/datetimepicker": "6.5.2",
|
|
@@ -92,6 +92,7 @@
|
|
|
92
92
|
"react-dom": "18.1.0",
|
|
93
93
|
"react-native": "0.70.5",
|
|
94
94
|
"react-native-big-list": "^1.6.0",
|
|
95
|
+
"react-native-blob-util": "^0.17.0",
|
|
95
96
|
"react-native-gesture-handler": "~2.8.0",
|
|
96
97
|
"react-native-paper": "^4.12.5",
|
|
97
98
|
"react-native-paper-dates": "^0.9.2",
|
|
@@ -529,25 +529,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
529
529
|
{this.renderDisplayTypes()}
|
|
530
530
|
{this.renderAggregatorFunctionsMenu()}
|
|
531
531
|
{!canRenderChart ? <RenderType /> : null}
|
|
532
|
-
|
|
533
|
-
{/*exportable && exportTableProps.pdf && (exportTableProps.pdf.footer) ? (
|
|
534
|
-
<td width="40px">
|
|
535
|
-
<ExportTable
|
|
536
|
-
{...exportTableProps}
|
|
537
|
-
excel = {false}
|
|
538
|
-
ref = {(el)=>{
|
|
539
|
-
if(el){
|
|
540
|
-
this.exportDataInstance = el;
|
|
541
|
-
}
|
|
542
|
-
}}
|
|
543
|
-
selector = {this.exportableDomId}
|
|
544
|
-
getAllData = {()=>{
|
|
545
|
-
return this.INITIAL_STATE.data;
|
|
546
|
-
}}
|
|
547
|
-
/>
|
|
548
|
-
</td>
|
|
549
|
-
) : null
|
|
550
|
-
*/}
|
|
532
|
+
{this.renderExportableMenu()}
|
|
551
533
|
{/*filters !== false && <td ><LocalFilter title = {this.props.title} fields ={this.state.columns} onChange={this.onLocalFiltersChange.bind(this)}/></td>*/}
|
|
552
534
|
</View>
|
|
553
535
|
</ScrollView>
|
|
@@ -11,7 +11,7 @@ import {showConfirm} from "$ecomponents/Dialog";
|
|
|
11
11
|
import Label from "$ecomponents/Label";
|
|
12
12
|
import Icon,{COPY_ICON} from "$ecomponents/Icon";
|
|
13
13
|
import filterUtils from "$cfilters";
|
|
14
|
-
import {sortBy,isDecimal,defaultVal,extendObj,isObjOrArray,isObj,defaultNumber,defaultStr,isFunction,defaultBool,defaultArray,defaultObj,isNonNullString,defaultDecimal} from "$utils";
|
|
14
|
+
import {sortBy,isDecimal,defaultVal,sanitizeSheetName,extendObj,isObjOrArray,isObj,defaultNumber,defaultStr,isFunction,defaultBool,defaultArray,defaultObj,isNonNullString,defaultDecimal} from "$utils";
|
|
15
15
|
import {Datagrid as DatagridContentLoader} from "$ecomponents/ContentLoader";
|
|
16
16
|
import React from "$react";
|
|
17
17
|
import DateLib from "$lib/date";
|
|
@@ -37,6 +37,7 @@ import notify from "$cnotify";
|
|
|
37
37
|
import FileSystem from "$file-system";
|
|
38
38
|
import sprintf from "$cutils/sprintf";
|
|
39
39
|
import { renderRowCell,formatValue } from "./utils";
|
|
40
|
+
import * as XLSX from "xlsx";
|
|
40
41
|
|
|
41
42
|
export const TIMEOUT = 100;
|
|
42
43
|
|
|
@@ -1623,6 +1624,204 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1623
1624
|
}
|
|
1624
1625
|
]
|
|
1625
1626
|
}
|
|
1627
|
+
getExportableFields(){
|
|
1628
|
+
return {
|
|
1629
|
+
fileName : {
|
|
1630
|
+
text : "Nom du fichier",
|
|
1631
|
+
format : "hashtag",
|
|
1632
|
+
required : true,
|
|
1633
|
+
},
|
|
1634
|
+
displayTotals : {
|
|
1635
|
+
type : "switch",
|
|
1636
|
+
label : "Exporter les entêtes des groupes",
|
|
1637
|
+
defaultValue :1,
|
|
1638
|
+
},
|
|
1639
|
+
/*abreviateValues : {
|
|
1640
|
+
text : "Abréger les valeurs numériques",
|
|
1641
|
+
type : "switch",
|
|
1642
|
+
},*/
|
|
1643
|
+
dateFormat : {
|
|
1644
|
+
text : "Format des dates",
|
|
1645
|
+
type : "dateFormat",
|
|
1646
|
+
required : true,
|
|
1647
|
+
},
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
/***@see : https://docs.sheetjs.com/docs/api/utilities */
|
|
1651
|
+
exportToExcel(){
|
|
1652
|
+
const skey = "export-to-excel";
|
|
1653
|
+
const isOnlytotal = this.state.displayOnlySectionListHeaders;
|
|
1654
|
+
let displayOnlyHeader = this.canDisplayOnlySectionListHeaders() && isOnlytotal;
|
|
1655
|
+
const sData = defaultObj(this.getSessionData(skey));
|
|
1656
|
+
return DialogProvider.open({
|
|
1657
|
+
title : "Paramètre d'export excel",
|
|
1658
|
+
data : sData,
|
|
1659
|
+
fields : {
|
|
1660
|
+
...this.getExportableFields(),
|
|
1661
|
+
sheetName : {
|
|
1662
|
+
label : 'Nom de la feuille excel',
|
|
1663
|
+
format : "hashtag",
|
|
1664
|
+
required : true,
|
|
1665
|
+
},
|
|
1666
|
+
exportOnlyTotal : displayOnlyHeader && {
|
|
1667
|
+
label : "Exporter uniquemnt les totaux",
|
|
1668
|
+
defaultValue : 0,
|
|
1669
|
+
type : "switch",
|
|
1670
|
+
},
|
|
1671
|
+
aggregatedValues : displayOnlyHeader ? {
|
|
1672
|
+
label : "Exporter uniquement les totaux aggrégées",
|
|
1673
|
+
defaultValue : 0,
|
|
1674
|
+
type : "switch",
|
|
1675
|
+
} : null,
|
|
1676
|
+
addEmptyRowAfterTotal : {
|
|
1677
|
+
|
|
1678
|
+
},
|
|
1679
|
+
},
|
|
1680
|
+
actions : [{text:'Exporter',icon : "check"}],
|
|
1681
|
+
onSuccess:({data:config})=>{
|
|
1682
|
+
this.setSessionData(skey,config);
|
|
1683
|
+
config.fileName = sprintf(config.fileName);
|
|
1684
|
+
config.sheetName = sanitizeSheetName(config.sheetName);
|
|
1685
|
+
const data = [];
|
|
1686
|
+
let totalColumns = 0;
|
|
1687
|
+
const cols = {};
|
|
1688
|
+
DialogProvider.close();
|
|
1689
|
+
Preloader.open("préparation des données...");
|
|
1690
|
+
const footers = this.getFooters();
|
|
1691
|
+
if(displayOnlyHeader && config.aggregatedValues){
|
|
1692
|
+
const fValues = this.getFooterValues();
|
|
1693
|
+
const headers = ["Fonction d'agrégation"];
|
|
1694
|
+
const aggregatorFunctions = this.aggregatorFunctions;
|
|
1695
|
+
Object.map(footers,(f,i)=>{
|
|
1696
|
+
const col = this.state.columns[i];
|
|
1697
|
+
if(!col || col.visible === false) return;
|
|
1698
|
+
headers.push(defaultStr(col.label,col.text));
|
|
1699
|
+
cols[i] = col;
|
|
1700
|
+
});
|
|
1701
|
+
data.push(headers);
|
|
1702
|
+
Object.map(aggregatorFunctions,(ag,i)=>{
|
|
1703
|
+
const d = [defaultStr(ag.label,ag.text,i)];
|
|
1704
|
+
Object.map(fValues,(footer,field)=>{
|
|
1705
|
+
if(!cols[field]) return;
|
|
1706
|
+
d.push(defaultNumber(footer[i]))
|
|
1707
|
+
});
|
|
1708
|
+
data.push(d);
|
|
1709
|
+
})
|
|
1710
|
+
} else {
|
|
1711
|
+
const headers = [];
|
|
1712
|
+
const hFooters = defaultObj(this.sectionListHeaderFooters);
|
|
1713
|
+
const agFunc = this.state.aggregatorFunction;
|
|
1714
|
+
const canExportOnlyTotal = isOnlytotal || (config.exportOnlyTotal && displayOnlyHeader);
|
|
1715
|
+
if(canExportOnlyTotal){
|
|
1716
|
+
headers.push("");
|
|
1717
|
+
}
|
|
1718
|
+
Object.map(this.state.columns,(col,i)=>{
|
|
1719
|
+
if(!isObj(col) || col.visible === false || this.isSelectableColumn(col,i) || i === this.getIndexColumnName()) return;
|
|
1720
|
+
if(canExportOnlyTotal && !(i in footers)) return;
|
|
1721
|
+
cols[i] = col;
|
|
1722
|
+
headers.push(defaultStr(col.label,col.text));
|
|
1723
|
+
totalColumns++;
|
|
1724
|
+
})
|
|
1725
|
+
data.push(headers);
|
|
1726
|
+
Object.map(this.state.data,(dat,index)=>{
|
|
1727
|
+
///si l'on a a faire à une colonne de type entete
|
|
1728
|
+
const d = [];
|
|
1729
|
+
if(dat.isSectionListHeader){
|
|
1730
|
+
if(!config.displayTotals && !canExportOnlyTotal) return;
|
|
1731
|
+
const {sectionListHeaderKey:key} = dat;
|
|
1732
|
+
const val = key === this.emptySectionListHeaderValue ? this.getEmptySectionListHeaderValue() : key;
|
|
1733
|
+
d.push(val);
|
|
1734
|
+
if(!canExportOnlyTotal){
|
|
1735
|
+
for(let i = 1;i<totalColumns;i++){
|
|
1736
|
+
d.push(null);
|
|
1737
|
+
}
|
|
1738
|
+
data.push(d);
|
|
1739
|
+
}
|
|
1740
|
+
const hF = hFooters[key];
|
|
1741
|
+
if(isObj(hF) && isNonNullString(agFunc)){
|
|
1742
|
+
const dd = [];
|
|
1743
|
+
Object.map(cols,(col,i)=>{
|
|
1744
|
+
if(i in hF){
|
|
1745
|
+
const ff = hF[i];
|
|
1746
|
+
dd.push(defaultNumber(ff[agFunc]));
|
|
1747
|
+
} else {
|
|
1748
|
+
dd.push(null);
|
|
1749
|
+
}
|
|
1750
|
+
});
|
|
1751
|
+
if(canExportOnlyTotal){
|
|
1752
|
+
dd.unshift(val);
|
|
1753
|
+
data.push(dd);
|
|
1754
|
+
} else {
|
|
1755
|
+
data.push(d);
|
|
1756
|
+
data.push(dd);
|
|
1757
|
+
}
|
|
1758
|
+
} else {
|
|
1759
|
+
data.push(d);
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
} else if(!canExportOnlyTotal) {
|
|
1763
|
+
Object.map(cols,(col,i)=>{
|
|
1764
|
+
const isDateField = defaultStr(col.type).toLowerCase().contains("date");
|
|
1765
|
+
d.push(this.renderRowCell({
|
|
1766
|
+
data : dat,
|
|
1767
|
+
rowData : dat,
|
|
1768
|
+
rowCounterIndex : index,
|
|
1769
|
+
rowIndex : index,
|
|
1770
|
+
formatValue : false,
|
|
1771
|
+
renderRowCell : false,
|
|
1772
|
+
columnField : defaultStr(col.field,i),
|
|
1773
|
+
columnDef :{
|
|
1774
|
+
...col,
|
|
1775
|
+
...(isDateField?{format:config.dateFormat}:{})
|
|
1776
|
+
}
|
|
1777
|
+
}));
|
|
1778
|
+
})
|
|
1779
|
+
data.push(d);
|
|
1780
|
+
}
|
|
1781
|
+
});
|
|
1782
|
+
}
|
|
1783
|
+
const wb = XLSX.utils.book_new();
|
|
1784
|
+
const ws = XLSX.utils.aoa_to_sheet(data);
|
|
1785
|
+
XLSX.utils.book_append_sheet(wb, ws, config.sheetName);
|
|
1786
|
+
FileSystem.writeExcel({...config,workbook:wb}).then(({path})=>{
|
|
1787
|
+
if(isNonNullString(path)){
|
|
1788
|
+
notify.success("Fichier enregistré dans le répertoire {0}".sprintf(path))
|
|
1789
|
+
}
|
|
1790
|
+
}).finally(()=>{
|
|
1791
|
+
Preloader.close();
|
|
1792
|
+
})
|
|
1793
|
+
}
|
|
1794
|
+
})
|
|
1795
|
+
}
|
|
1796
|
+
exportToPdf(){
|
|
1797
|
+
|
|
1798
|
+
}
|
|
1799
|
+
renderExportableMenu(){
|
|
1800
|
+
if(this.isDashboard() || !defaultStr(this.state.displayType).toLowerCase().contains("table")) return null;
|
|
1801
|
+
const items = [];
|
|
1802
|
+
if(this.canExportToExcel()){
|
|
1803
|
+
items.push({
|
|
1804
|
+
text : "Exporter au format excel",
|
|
1805
|
+
icon : "file-excel",
|
|
1806
|
+
onPress: this.exportToExcel.bind(this),
|
|
1807
|
+
})
|
|
1808
|
+
}
|
|
1809
|
+
if(false && this.canExportToPDF()){
|
|
1810
|
+
items.push({
|
|
1811
|
+
text : "Exporter au format pdf",
|
|
1812
|
+
icon : "file-pdf-box",
|
|
1813
|
+
onPress : this.exportToPdf.bind(this)
|
|
1814
|
+
})
|
|
1815
|
+
}
|
|
1816
|
+
if(!items.length) return null;
|
|
1817
|
+
return <Menu
|
|
1818
|
+
items = {items}
|
|
1819
|
+
title ="Export des données du tableau"
|
|
1820
|
+
anchor = {(a)=>{
|
|
1821
|
+
return <Icon title = {"Exporter les données du tableau"} {...a} name={"export"}/>
|
|
1822
|
+
}}
|
|
1823
|
+
/>
|
|
1824
|
+
}
|
|
1626
1825
|
renderDisplayTypes(){
|
|
1627
1826
|
const m = [];
|
|
1628
1827
|
let activeType = null,hasFoundChart = false,hasFoundTable = false;
|
|
@@ -1830,7 +2029,7 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1830
2029
|
const chartType = displayTypes[this.state.displayType];
|
|
1831
2030
|
if(!isObj(chartType) || !isNonNullString(chartType.type)) return null;
|
|
1832
2031
|
if(typeof chartType.isRendable =='function' && chartType.isRendable(this.getChartIsRendableArgs()) === false) {
|
|
1833
|
-
console.warn("impossible d'afficher le graphe de type ",chartType.label," car le type de données requis pour le rendu de ce graphe est invalide")
|
|
2032
|
+
//console.warn("impossible d'afficher le graphe de type ",chartType.label," car le type de données requis pour le rendu de ce graphe est invalide")
|
|
1834
2033
|
return null;
|
|
1835
2034
|
}
|
|
1836
2035
|
const isDonut = chartType.isDonut || chartType.isRadial;
|
|
@@ -3172,7 +3371,7 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
3172
3371
|
différent du td d'un table et ne doit pas être un TableColumn de md
|
|
3173
3372
|
*/
|
|
3174
3373
|
renderRowCell (arg){
|
|
3175
|
-
let {rowData,rowKey,rowIndex,handleSelectableColumn,rowCounterIndex,renderRowCell:customRenderRowCell,isSectionListHeader,columnDef,columnField} = arg;
|
|
3374
|
+
let {rowData,rowKey,rowIndex,handleSelectableColumn,formatValue,rowCounterIndex,renderRowCell:customRenderRowCell,isSectionListHeader,columnDef,columnField} = arg;
|
|
3176
3375
|
const renderText = isSectionListHeader === true || customRenderRowCell === false ? true : false;
|
|
3177
3376
|
if(!isObj(rowData)) return renderText ? null : {render:null,extra:{}};
|
|
3178
3377
|
rowIndex = isDecimal(rowIndex)? rowIndex : isDecimal(index)? index : undefined;
|
|
@@ -3196,6 +3395,7 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
3196
3395
|
}
|
|
3197
3396
|
return renderRowCell({
|
|
3198
3397
|
...arg,
|
|
3398
|
+
formatValue,
|
|
3199
3399
|
context : this,
|
|
3200
3400
|
getRowKey : this.getRowKey.bind(this),
|
|
3201
3401
|
abreviateValues : this.state.abreviateValues,
|
|
@@ -12,8 +12,9 @@ import {Flag} from "$ecomponents/Countries";
|
|
|
12
12
|
import { StyleSheet } from "react-native";
|
|
13
13
|
|
|
14
14
|
export const renderRowCell = (arg)=>{
|
|
15
|
-
let {rowData,getRowKey,context,renderRowCell:customRenderRowCell,abreviateValues,isSectionListHeader,rowIndex,index,rowCounterIndex,columnDef,columnField} = arg;
|
|
15
|
+
let {rowData,getRowKey,context,formatValue:customFormatValue,renderRowCell:customRenderRowCell,abreviateValues,isSectionListHeader,rowIndex,index,rowCounterIndex,columnDef,columnField} = arg;
|
|
16
16
|
context = context || this;
|
|
17
|
+
const canFormatValue = customFormatValue !== false ? true : false;
|
|
17
18
|
const renderText = isSectionListHeader === true || customRenderRowCell === false ? true : false;
|
|
18
19
|
rowIndex = isDecimal(rowIndex)? rowIndex : isDecimal(index)? index : undefined;
|
|
19
20
|
rowCounterIndex = isDecimal(rowCounterIndex) ? rowCounterIndex : isDecimal(rowIndex)? rowIndex+1 : defaultDecimal(rowCounterIndex);
|
|
@@ -120,16 +121,18 @@ export const renderRowCell = (arg)=>{
|
|
|
120
121
|
if(isFunction(renderProps)){
|
|
121
122
|
renderProps = renderProps.call(context,renderArgs);
|
|
122
123
|
}
|
|
123
|
-
|
|
124
|
+
if(canFormatValue){
|
|
125
|
+
_render = formatValue(_render,columnDef.format,abreviateValues);
|
|
126
|
+
}
|
|
124
127
|
if(!renderText && _render && isObj(renderProps)){
|
|
125
128
|
let Component = defaultVal(renderProps.Component,Label);
|
|
126
129
|
delete renderProps.Component;
|
|
127
130
|
_render = <Component {...renderProps}>{_render}</Component>
|
|
128
131
|
}
|
|
129
|
-
if(typeof _render =='boolean'){
|
|
130
|
-
_render = _render ? "Oui" : "Non";
|
|
131
|
-
}
|
|
132
132
|
if(renderText){
|
|
133
|
+
if(typeof _render =='number' || typeof _render =='boolean' || typeof _render =="string"){
|
|
134
|
+
return _render;
|
|
135
|
+
}
|
|
133
136
|
return React.getTextContent(_render);
|
|
134
137
|
}
|
|
135
138
|
if((typeof _render ==='string' || typeof _render =='number')){
|
|
@@ -181,6 +184,9 @@ export const renderSelectFieldCell= ({rowData,columnDef,columnField})=>{
|
|
|
181
184
|
|
|
182
185
|
export const formatValue = (value,format,abreviateValues)=>{
|
|
183
186
|
if(typeof value !='number') return value;
|
|
187
|
+
if(typeof value =='boolean'){
|
|
188
|
+
return value ? "Oui" : "Non";
|
|
189
|
+
}
|
|
184
190
|
if(format && typeof format =='string' && format.toLowerCase() =='money'){
|
|
185
191
|
return abreviateValues? value.abreviate2FormatMoney() : value.formatMoney();
|
|
186
192
|
}
|
|
@@ -295,6 +295,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
295
295
|
{this.renderSectionListMenu()}
|
|
296
296
|
{this.renderDisplayTypes()}
|
|
297
297
|
{this.renderAggregatorFunctionsMenu()}
|
|
298
|
+
{this.renderExportableMenu()}
|
|
298
299
|
<View pointerEvents={pointerEvents} testID={testID+"_HeaderPagination"} style = {styles.paginationItem}>
|
|
299
300
|
<BottomSheetMenu
|
|
300
301
|
testID={testID+"_HeaderMenus"}
|
|
@@ -55,7 +55,7 @@ const Provider = React.forwardRef((props,innerRef)=>{
|
|
|
55
55
|
},
|
|
56
56
|
close : (props)=>{
|
|
57
57
|
if(!state.visible) return;
|
|
58
|
-
return setState({...state,...props,visible:false});
|
|
58
|
+
return setState({...state,...defaultObj(props),visible:false});
|
|
59
59
|
},
|
|
60
60
|
};
|
|
61
61
|
React.setRef(ref,context);
|
|
@@ -26,7 +26,7 @@ const FormDataDialogProvider = React.forwardRef((props,innerRef)=>{
|
|
|
26
26
|
if(formRef.current && formRef.current.formDataContext && formRef.current.formDataContext.getData){
|
|
27
27
|
sData.data = formRef.current.formDataContext.getData();
|
|
28
28
|
}
|
|
29
|
-
return setState({...
|
|
29
|
+
return setState({...sData,onDismiss:undefined,...defaultObj(props),visible:true})
|
|
30
30
|
},
|
|
31
31
|
close : (props)=>{
|
|
32
32
|
if(!state.visible) return;
|