@fto-consult/expo-ui 2.17.0 → 2.18.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.
@@ -24,7 +24,7 @@ import { StyleSheet,Dimensions,useWindowDimensions} from "react-native";
24
24
  import Preloader from "$ecomponents/Preloader";
25
25
  import Checkbox from "../Checkbox";
26
26
  import { TouchableRipple } from "react-native-paper";
27
- import { evalSingleValue } from "../Footer";
27
+ import { evalSingleValue,Footer } from "../Footer";
28
28
  import i18n from "$i18n";
29
29
  import { makePhoneCall,canMakePhoneCall as canMakeCall} from "$makePhoneCall";
30
30
  import copyToClipboard from "$capp/clipboard";
@@ -35,6 +35,8 @@ import stableHash from "stable-hash";
35
35
  import DatagridProgressBar from "./ProgressBar";
36
36
  import {Flag} from "$ecomponents/Countries"
37
37
  import View from "$ecomponents/View";
38
+ import {Menu} from "$ecomponents/BottomSheet";
39
+ import {styles as tableStyles} from "$ecomponents/Table";
38
40
 
39
41
  export const arrayValueSeparator = ", ";
40
42
 
@@ -54,7 +56,6 @@ export default class CommonDatagridComponent extends AppComponent {
54
56
  let {
55
57
  data,
56
58
  selectedRows,
57
- sectionListColumns : cSectionListColumns,//les colonnes à utiliser pour le rendue des sectionList
58
59
  ...rest
59
60
  } = props;
60
61
  if(this.bindResizeEvents()){
@@ -69,7 +70,7 @@ export default class CommonDatagridComponent extends AppComponent {
69
70
  data = (data && typeof data == 'object')? Object.toArray(data):[];
70
71
  let sRows = {}
71
72
  Object.map(selectedRows,(row,i)=>{
72
- if(isObj(row)){
73
+ if(this.canSelectRow(row)){
73
74
  sRows[this.getRowKey(row,i)] = {...row};
74
75
  }
75
76
  });
@@ -113,6 +114,9 @@ export default class CommonDatagridComponent extends AppComponent {
113
114
  getSectionListHeaderProp : {value : typeof this.props.getSectionListHeader =='function'? this.props.getSectionListHeader : undefined},
114
115
  sectionListData : {value : {}},//l'ensemble des données de sectionList
115
116
  hasFoundSectionData : {value : {current: false}},
117
+ sectionListHeaderFooters : {value : {}},
118
+ sectionListDataSize : {value : {current : 0}},
119
+ sectionListColumnsSize : {value : {current:0}}, //la taille du nombre d'éléments de section dans les colonnes
116
120
  })
117
121
  this.isLoading = this.isLoading.bind(this);
118
122
  this.getProgressBar = this.getProgressBar.bind(this);
@@ -192,15 +196,26 @@ export default class CommonDatagridComponent extends AppComponent {
192
196
  this.currentDataSources = Object.toArray(this.currentDataSources);
193
197
  }
194
198
  }
199
+ /*** si une ligne peut être selectionable */
200
+ canSelectRow(row){
201
+ return isObj(row) && row.isSectionListHeader !== true ? true : false;
202
+ }
195
203
  prepareSectionListColumns(props){
196
204
  props = defaultObj(props,this.props);
197
- return Array.isArray(props.sectionListColumns) ? props.sectionListColumns : [];
205
+ const l = {};
206
+ (Array.isArray(props.sectionListColumns) ? props.sectionListColumns : []).map((col)=>{
207
+ if(isNonNullString(col)){
208
+ l[col.trim()] = {};
209
+ }
210
+ })
211
+ return l;
198
212
  }
199
213
  /*** récupère la liste des colonnes à utiliser pour le rendu des sectionList, ces colonnes doivent figurer dans la liste des colonnes du tableu */
200
- getSectionListColumns(prepared){
201
- if(Array.isArray(this.state.sectionListColumns) && this.state.sectionListColumns.length) return this.state.sectionListColumns;
202
- if(prepared === false) return [];
203
- return this.prepareSectionListColumns();
214
+ getSectionListColumns(){
215
+ if(!isObj(this.state.sectionListColumns)){
216
+ return this.prepareSectionListColumns();
217
+ }
218
+ return this.state.sectionListColumns;
204
219
  }
205
220
  bindResizeEvents(){
206
221
  return false;
@@ -383,6 +398,7 @@ export default class CommonDatagridComponent extends AppComponent {
383
398
  }
384
399
  /**** fonction appelée lorsque l'on clique sur la checkbox permettant de sélectionner la ligne */
385
400
  handleRowToggle ({row,rowIndex,rowData,rowKey,index, selected,cb,callback},cb2){
401
+ if(!this.canSelectRow(row)) return ;
386
402
  if(typeof rowKey !=='string' && typeof rowKey !=='number') return;
387
403
  let selectableMultiple = defaultVal(this.props.selectableMultiple,true);
388
404
  rowIndex = defaultNumber(rowIndex,index);
@@ -493,6 +509,9 @@ export default class CommonDatagridComponent extends AppComponent {
493
509
  isSelectableColumn(columnDef,columnField){
494
510
  return isObj(columnDef) && defaultStr(columnDef.field,columnField) === this.getSelectableColumName();
495
511
  }
512
+ isIndexColumn(columnDef,columnField){
513
+ return isObj(columnDef) && defaultStr(columnDef.field,columnField) === this.getIndexColumnName();
514
+ }
496
515
  initColumnsCallback(){}
497
516
  initColumns (columns){
498
517
  this.state.columns = {};
@@ -532,7 +551,7 @@ export default class CommonDatagridComponent extends AppComponent {
532
551
  const headerCol = Object.clone(headerCol1);
533
552
  if(isAccordion && headerCol.accordion === false) return null;
534
553
  let header = {...headerCol};
535
- header.field = header.field || headerIndex
554
+ header.field = defaultStr(header.field, headerIndex)
536
555
  /**** pour ignorer une colonne du datagrid, il suffit de passer le paramètre datagrid à false */
537
556
  if(!isNonNullString(header.field) || header.datagrid === false) {
538
557
  return;
@@ -742,7 +761,7 @@ export default class CommonDatagridComponent extends AppComponent {
742
761
  if(typeof this.props.onSort =='function' && this.props.onSort({...sort,context:this,sort,data:this.INITIAL_STATE.data,fields:this.state.columns,columns:this.state.columns}) === false){
743
762
  return;
744
763
  }
745
- this.prepareData({data:this.state.data,updateFooters:false},(state)=>{
764
+ this.prepareData({data:this.INITIAL_STATE.data,updateFooters:false},(state)=>{
746
765
  this.setState(state);
747
766
  });
748
767
  }
@@ -789,7 +808,7 @@ export default class CommonDatagridComponent extends AppComponent {
789
808
  const customMenu = []
790
809
  Object.map(this.props.customMenu,(menu,i)=>{
791
810
  if(isObj(menu)){
792
- const {onPress,menu,label,text,children,...rest} = menu;
811
+ const {onPress,label,text,children,...rest} = menu;
793
812
  const args = {context:this,refresh:this.refresh.bind(this)};
794
813
  const lCB = defaultVal(children,label,text);
795
814
  const labelText = typeof lCB ==='function'? lCB(args) : lCB;
@@ -962,21 +981,80 @@ export default class CommonDatagridComponent extends AppComponent {
962
981
  }
963
982
  return null;
964
983
  }
984
+ toggleColumnInSectionList(columnName){
985
+ if(!isNonNullString(columnName) || !isObj(this.state.columns[columnName])) return;
986
+ if(!isObj(this.state.sectionListColumns) || !Array.isArray(this.preparedColumns?.sectionListColumnsMenuItems))return;
987
+ const menuItems = this.preparedColumns?.sectionListColumnsMenuItems;
988
+ if(!menuItems.length) return;
989
+ const sectionListColumns = {...this.state.sectionListColumns};
990
+ if(isObj(sectionListColumns[columnName])){
991
+ delete sectionListColumns[columnName];
992
+ } else {
993
+ sectionListColumns[columnName] = {};
994
+ }
995
+ const {sectionListColumns:pSListColumns} = this.prepareColumns({sectionListColumns});
996
+ this.setIsLoading(true,()=>{
997
+ this.prepareData({data:this.INITIAL_STATE.data,sectionListColumns:pSListColumns},(state)=>{
998
+ this.setState({...state,sectionListColumns:pSListColumns},()=>{
999
+ this.setIsLoading(false);
1000
+ });
1001
+ });
1002
+ })
1003
+ }
1004
+ removeAllColumnsInSectionList(){
1005
+ const {sectionListColumns} = this.prepareColumns({sectionListColumns:{}});
1006
+ this.setIsLoading(true,()=>{
1007
+ this.prepareData({data:this.INITIAL_STATE.data,sectionListColumns},(state)=>{
1008
+ this.setState({...state,sectionListColumns},()=>{
1009
+ this.setIsLoading(false);
1010
+ });
1011
+ });
1012
+ })
1013
+ }
1014
+ /*** permet d'effectuer le rendu des colonnes groupable dans le menu item */
1015
+ renderSectionListMenu(){
1016
+ const m = Array.isArray(this.preparedColumns?.sectionListColumnsMenuItems)? this.preparedColumns?.sectionListColumnsMenuItems : [];
1017
+ if(!m.length){
1018
+ return null;
1019
+ }
1020
+ const isMobile = isMobileOrTabletMedia();
1021
+ return <Menu
1022
+ title = {"Grouper les données du tableau"}
1023
+ testID = {"RN_DatagridSectionListMenu"}
1024
+ anchor = {(props)=>{
1025
+ return <Icon {...props} name='format-list-group' title={"Grouper les éléments du tableau"}></Icon>
1026
+ }}
1027
+ items = {[
1028
+ !isMobile && {
1029
+ text : "Grouper par",
1030
+ icon : "group",
1031
+ closeOnPress : false,
1032
+ divider : true,
1033
+ },
1034
+ this.sectionListColumnsSize.current && {
1035
+ text : "Supprimer les groupes",
1036
+ icon: "ungroup",
1037
+ divider : true,
1038
+ onPress : ()=>{
1039
+ setTimeout(()=>{
1040
+ this.removeAllColumnsInSectionList();
1041
+ },300)
1042
+ }
1043
+ },
1044
+ ...m,
1045
+ ]}
1046
+ />
1047
+ }
965
1048
  prepareColumns (args){
966
1049
  this.beforePrepareColumns();
967
1050
  args = defaultObj(args);
968
- const sectionListColumns = [];
969
- const sListColumns = this.getSectionListColumns();
970
- const allSlistColumns = {};
971
- Object.map(sListColumns,(i)=>{
972
- if(isNonNullString(i)){
973
- allSlistColumns[i.trim()] = true;
974
- }
975
- });
1051
+ const sectionListColumns = {};
1052
+ const sListColumns = isObj(args.sectionListColumns) ? args.sectionListColumns : this.getSectionListColumns();
976
1053
  const filteredColumns = isObjOrArray(args.filteredColumns)?args.filteredColumns : isObjOrArray(this.state.filteredColumns) ? this.state.filteredColumns : {};
977
1054
  const columns = args.columns || this.state.columns;
978
1055
  const currentSortedColumn = isObj(args.sortedColumn) && args.sortedColumn.column? args.sortedColumn : defaultObj(this.sortRef.current);
979
1056
  const visibleColumns = [],headerFilters = [],visibleColumnsNames={};
1057
+ const sectionListColumnsMenuItems = [];
980
1058
  const sortable = defaultBool(this.props.sortable,true);
981
1059
  const sortedColumns = {};
982
1060
  let sortedColumnsLength = 0;
@@ -989,6 +1067,7 @@ export default class CommonDatagridComponent extends AppComponent {
989
1067
  const widths = {};
990
1068
  let totalWidths = 0;
991
1069
  let columnIndex = 0,visibleColumnIndex=0;
1070
+ this.sectionListColumnsSize.current = 0;
992
1071
  Object.map(columns,(header,headerIndex) => {
993
1072
  let {
994
1073
  field,
@@ -1035,7 +1114,12 @@ export default class CommonDatagridComponent extends AppComponent {
1035
1114
  const title = header.text = header.text || header.label || header.title||header.field
1036
1115
  visibleColumnsNames[header.field] = visible ? true : false;
1037
1116
  visibleColumns.push({
1038
- onPress : ()=>{this.toggleColumnVisibility(header.field);return false},
1117
+ onPress : ()=>{
1118
+ setTimeout(() => {
1119
+ this.toggleColumnVisibility(header.field);
1120
+ },300);
1121
+ return false;
1122
+ },
1039
1123
  title : title,
1040
1124
  icon : visible?CHECKED_ICON_NAME : null,
1041
1125
  });
@@ -1062,9 +1146,7 @@ export default class CommonDatagridComponent extends AppComponent {
1062
1146
  sortedColumns[field] = restCol.label;
1063
1147
  sortedColumnsLength++;
1064
1148
  }
1065
- if(this.props.groupable !== false && header.groupable !== false && allSlistColumns[field]){
1066
- sectionListColumns.push(field);///les colonnes de sections
1067
- }
1149
+
1068
1150
  colFilter = colFilter && filters !== false ? true : false;
1069
1151
  const sortedProps = isColumnSorted ? {...sortedColumn} : {};
1070
1152
  let filterProps = {};
@@ -1121,6 +1203,30 @@ export default class CommonDatagridComponent extends AppComponent {
1121
1203
  key : header.field,
1122
1204
  filter :colFilter,
1123
1205
  },headerFilters)
1206
+
1207
+ if(this.props.groupable !== false && header.groupable !== false && !this.isSelectableColumn(header,header.field) && !this.isIndexColumn(header,header.field)){
1208
+ const isInSectionListHeader = isObj(sListColumns[field]);
1209
+ if(isInSectionListHeader){
1210
+ sectionListColumns[field] = {
1211
+ ...header,
1212
+ width,
1213
+ type,
1214
+ ...sListColumns[field],
1215
+ };///les colonnes de sections
1216
+ this.sectionListColumnsSize.current++;
1217
+ }
1218
+ sectionListColumnsMenuItems.push({
1219
+ field,
1220
+ onPress : ()=>{
1221
+ setTimeout(()=>{
1222
+ this.toggleColumnInSectionList(field);
1223
+ },300)
1224
+ return false;
1225
+ },
1226
+ title : title,
1227
+ icon : isInSectionListHeader?CHECKED_ICON_NAME : null,
1228
+ });
1229
+ }
1124
1230
  columnIndex++;
1125
1231
  visibleColumnIndex++;
1126
1232
 
@@ -1135,6 +1241,7 @@ export default class CommonDatagridComponent extends AppComponent {
1135
1241
  this.preparedColumns.widths = widths;
1136
1242
  this.preparedColumns.totalWidths = totalWidths;
1137
1243
  this.preparedColumns.sectionListColumns = sectionListColumns;
1244
+ this.preparedColumns.sectionListColumnsMenuItems = sectionListColumnsMenuItems;
1138
1245
  return this.preparedColumns;
1139
1246
  }
1140
1247
  getPaginatedSelectedRows(data){
@@ -1149,8 +1256,9 @@ export default class CommonDatagridComponent extends AppComponent {
1149
1256
  }
1150
1257
 
1151
1258
  /**** s'il s'agit d'une section list */
1152
- isSectionList(){
1153
- return !this.isPivotDatagrid() && Array.isArray(this.state.sectionListColumns) && this.state.sectionListColumns.length ? true : false;
1259
+ isSectionList(sectionListColumns){
1260
+ sectionListColumns = isObj(sectionListColumns) ? sectionListColumns : this.state.sectionListColumns;
1261
+ return !this.isPivotDatagrid() && isObj(sectionListColumns) && Object.size(sectionListColumns,true) ? true : false;
1154
1262
  }
1155
1263
  /**** si le datagrid admet les sectionDatas */
1156
1264
  hasSectionListData(){
@@ -1169,45 +1277,44 @@ export default class CommonDatagridComponent extends AppComponent {
1169
1277
  }
1170
1278
  return sectionListHeader.trim();
1171
1279
  }
1280
+ getSectionListDataSize(){
1281
+ return defaultNumber(this.sectionListDataSize.current)
1282
+ }
1172
1283
  prepareData(args,cb){
1173
- let {pagination,data,force,updateFooters} = defaultObj(args);
1284
+ let {pagination,data,force,sectionListColumns,updateFooters} = defaultObj(args);
1174
1285
  cb = typeof cb ==='function'? cb : typeof args.cb == 'function'? args.cb : undefined;
1286
+ sectionListColumns = isObj(sectionListColumns) ? sectionListColumns : this.state.sectionListColumns;
1175
1287
  let isArr = Array.isArray(data);
1176
1288
  //let push = (d,index) => isArr ? newData.push(d) : newData[index] = d;
1177
1289
  const hasLocalFilter = this.props.filters !== false && this.hasLocalFilters;
1178
1290
  let footersColumns = this.getFooterFields(),hasFooterFields = Object.size(footersColumns,true);
1179
1291
  const canUpdateFooters = !!(updateFooters !== false && hasFooterFields);
1180
1292
  this.hasFoundSectionData.current = false;
1181
- if(hasLocalFilter || !isArr || canUpdateFooters || this.isSectionList()) {
1293
+ this.sectionListDataSize.current = 0;
1294
+ const isSList = this.isSectionList(sectionListColumns);
1295
+ if(hasLocalFilter || !isArr || canUpdateFooters || isSList) {
1182
1296
  if(canUpdateFooters){
1183
1297
  this.___evaluatedFootersValues = {}
1184
1298
  }
1185
1299
  const newData = [];
1186
- const columns = {};
1187
- let hasSectionColumns = false;
1188
- let sectionListColumnsSize = 0;
1189
- if(this.isSectionList()){
1300
+ const columns = sectionListColumns;
1301
+ const sectionListColumnsSize = this.sectionListColumnsSize.current;
1302
+ const hasSectionColumns = this.sectionListColumnsSize.current > 0;
1303
+ if(isSList){
1190
1304
  Object.map(this.sectionListData,(v,i)=>{
1191
1305
  delete this.sectionListData[i];
1192
1306
  });
1193
- Object.map(this.getSectionListColumns(false),(col)=>{
1194
- if(this.hasColumn(col)){
1195
- columns[col]= this.state.columns[col];
1196
- hasSectionColumns = true;
1197
- sectionListColumnsSize++;
1198
- }
1307
+ //on réinnitialise tous les footes
1308
+ Object.map(this.sectionListHeaderFooters,(v,i)=>{
1309
+ delete this.sectionListHeaderFooters[i];
1199
1310
  })
1200
1311
  }
1312
+ let currentSectionListFooter = null;
1201
1313
  const sectionListData = this.sectionListData;//l'ensemble des données de sectionList
1202
1314
  Object.map(data,(d,i,rowIndex)=>{
1203
1315
  if(!isObj(d) || (hasLocalFilter && this.doLocalFilter({rowData:d,rowIndex:i}) === false)){
1204
1316
  return;
1205
1317
  }
1206
- if(canUpdateFooters){
1207
- Object.map(footersColumns,(columnDef,field)=>{
1208
- evalSingleValue({data:d,columnDef,field,result:this.___evaluatedFootersValues,displayLabel:false})
1209
- });
1210
- }
1211
1318
  if(hasSectionColumns){
1212
1319
  let sHeader = this.getSectionListHeader({data:d,columnsLength : sectionListColumnsSize,fieldsSize:sectionListColumnsSize,sectionListColumnsLength:sectionListColumnsSize,sectionListColumnsSize,allData:data,rowData:d,index:i,rowIndex,context:this,columns,fields:columns});
1213
1320
  if(sHeader === false) return;//on omet la donnée si la fonction de récupération de son header retourne false
@@ -1217,20 +1324,35 @@ export default class CommonDatagridComponent extends AppComponent {
1217
1324
  } else return;
1218
1325
  }
1219
1326
  let r = this.formatSectionListHeader(sHeader);
1220
- sectionListData[r] = defaultArray(sectionListData[r]);
1327
+ if(!Array.isArray(sectionListData[r])){
1328
+ sectionListData[r] = [];
1329
+ this.sectionListDataSize.current++;
1330
+ }
1221
1331
  sectionListData[r].push(d);
1332
+ if(canUpdateFooters){
1333
+ this.sectionListHeaderFooters[r] = defaultObj(this.sectionListHeaderFooters[r]);
1334
+ currentSectionListFooter = this.sectionListHeaderFooters[r];
1335
+ }
1222
1336
  this.hasFoundSectionData.current = true;
1223
1337
  }
1338
+ if(canUpdateFooters){
1339
+ const result = [this.___evaluatedFootersValues]
1340
+ if(currentSectionListFooter){
1341
+ result.push(currentSectionListFooter);
1342
+ }
1343
+ Object.map(footersColumns,(columnDef,field)=>{
1344
+ evalSingleValue({data:d,columnDef,field,result,displayLabel:false})
1345
+ });
1346
+ }
1224
1347
  newData.push(d);
1225
1348
  //push(d,i);
1226
1349
  });
1227
1350
  data = newData;
1228
- }
1229
- let sortConfig = null;
1351
+ }
1230
1352
  if(this.canAutoSort() && isNonNullString(this.sortRef.current.column)){
1231
1353
  if(isObj(this.state.columns) && this.state.columns[this.sortRef.current.column]){
1232
1354
  let field = this.state.columns[this.sortRef.current.column];
1233
- sortConfig = Object.assign({},this.sortRef.current);
1355
+ const sortConfig = Object.assign({},this.sortRef.current);
1234
1356
  sortConfig.getItem = (item,columnName,{getItem})=>{
1235
1357
  if(isObj(item) && (field.type =='decimal' || field.type =="number")){
1236
1358
  const v = item[columnName];
@@ -1238,25 +1360,21 @@ export default class CommonDatagridComponent extends AppComponent {
1238
1360
  }
1239
1361
  return getItem(item,columnName);
1240
1362
  }
1241
- //data = sortBy(data,sortConfig);//on trie tout d'abord les données
1363
+ data = sortBy(data,sortConfig);//on trie tout d'abord les données
1242
1364
  }
1243
1365
  }
1366
+ this.INITIAL_STATE.data = data;
1244
1367
  if(this.hasFoundSectionData.current){
1245
1368
  data = [];
1246
1369
  for(let i in this.sectionListData){
1247
- this.sectionListData[i] = sortConfig ? sortBy(this.sectionListData[i],sortConfig):this.sectionListData[i];
1370
+ //this.sectionListData[i] = sortConfig ? sortBy(this.sectionListData[i],sortConfig):this.sectionListData[i];
1248
1371
  //const v = i;// === this.emptySectionListHeaderValue ? "" : i;
1249
1372
  data.push({isSectionListHeader:true,sectionListHeaderKey:i});
1250
1373
  this.sectionListData[i].map((d)=>{
1251
1374
  data.push(d);
1252
1375
  })
1253
1376
  }
1254
- } else {
1255
- if(sortConfig){
1256
- data = sortBy(data,sortConfig);
1257
- }
1258
- }
1259
- this.INITIAL_STATE.data = data;
1377
+ }
1260
1378
  if(!this.hasSectionListData() && this.canPaginateData()){
1261
1379
  pagination = this.initPagination(pagination);
1262
1380
  pagination.rows = data.length;
@@ -1290,10 +1408,10 @@ export default class CommonDatagridComponent extends AppComponent {
1290
1408
  if(sectionListColumnsSize == 1){
1291
1409
  d.push(txt);
1292
1410
  } else {
1293
- d.push("{0} : {0}".sprintf(defaultStr(field.label,field.txt),txt))
1411
+ d.push("{0} : {1}".sprintf(defaultStr(field.label,field.txt),txt))
1294
1412
  }
1295
- })
1296
- return d.length ? d.join(",") : undefined;
1413
+ });
1414
+ return d.length ? d.join(arrayValueSeparator) : undefined;
1297
1415
  }
1298
1416
  /*** retourne le type d'item à rendre à la fonction flashlist
1299
1417
  * @see : https://shopify.github.io/flash-list/docs/guides/section-list
@@ -1306,23 +1424,60 @@ export default class CommonDatagridComponent extends AppComponent {
1306
1424
  if(!this.hasSectionListData()) return null;
1307
1425
  args = defaultObj(args);
1308
1426
  let {item,rowProps,rowStyle} = args;
1309
- if(!isObj(item) || item.isSectionListHeader !== true) return null;
1427
+ if(!isObj(item) || item.isSectionListHeader !== true || !isNonNullString(item.sectionListHeaderKey)) return null;
1310
1428
  args.isAccordion = this.isAccordion();
1311
1429
  args.columns = this.preparedColumns.visibleColumns;
1312
1430
  args.columnsNames = this.preparedColumns.visibleColumnsNames;
1313
- const label = item.sectionListHeaderKey === this.emptySectionListHeaderValue ? "Valeur vide" : item.sectionListHeaderKey;
1431
+ const key = item.sectionListHeaderKey;
1432
+ const label = key === this.emptySectionListHeaderValue ? defaultStr(this.props.sectionListHeaderEmptyValue,"N/A") : key;
1314
1433
  const style = typeof this.props.getSectionListHeaderStyle =='function' ? this.props.getSectionListHeaderStyle(args) : null;
1434
+ const cStyle = typeof this.props.getSectionListHeaderContentContainerStyle =="function" ?this.props.getSectionListHeaderContentContainerStyle(args) : undefined;
1435
+ const lStyle = typeof this.props.getSectionListHeaderLabelStyle =='function' ? this.props.getSectionListHeaderLabelStyle(args) : null;
1436
+
1315
1437
  rowProps = defaultObj(rowProps);
1316
- rowProps.testID = "RN_DatagridSectionListHeder_"+defaultVal(args.rowIndex,args.index)
1438
+ const testID = rowProps.testID = defaultStr(args.testID,"RN_DatagridSectionListHeader")+"_"+defaultVal(args.rowIndex,args.index)
1317
1439
  if(Array.isArray(rowStyle)){
1318
- rowStyle.push(theme.styles.justifyContentCenter);
1319
- rowStyle.push(theme.styles.alignItemsCenter);
1320
- rowStyle.push(theme.styles.ml1,theme.styles.mr1);
1321
1440
  if(style){
1322
1441
  rowStyle.push(style);
1323
1442
  }
1324
1443
  }
1325
- return <Label textBold fontSize={16} testID={"RN_DatagridSectionListHeader_"+args.index} style={[theme.styles.w100]}>{label}</Label>
1444
+ let cells = null;
1445
+ if(this.state.showFooters && isObj(this.sectionListHeaderFooters[key])){
1446
+ const {visibleColumnsNames,widths} = defaultObj(this.preparedColumns);
1447
+ if(isObj(visibleColumnsNames) &&isObj(widths)){
1448
+ cells = [];
1449
+ const footers = this.sectionListHeaderFooters[key];
1450
+ Object.map(visibleColumnsNames,(v,column)=>{
1451
+ if(typeof widths[column] !== 'number') return null;
1452
+ const width = widths[column];
1453
+ if(!column) return null;
1454
+ const key = key+column;
1455
+ if(!column || !this.state.columns[column] || !footers[column]) {
1456
+ if(this.isAccordion()) return null;
1457
+ cells.push(<View key={key} testID={testID+"_FooterCellContainer"+key} style={[tableStyles.headerItemOrCell,{width}]}>
1458
+
1459
+ </View>)
1460
+ } else {
1461
+ const footer = footers[column];
1462
+ cells.push(<View key={key} testID={testID+"_FooterCellContainer"+key} style={[tableStyles.headerItemOrCell,{width,alignItems:'flex-start',justifyContent:'flex-start'}]}>
1463
+ <Footer
1464
+ key = {key}
1465
+ testID={testID+"_FooterItem_"+key}
1466
+ {...footer}
1467
+ displayLabel = {false}
1468
+ //anchorProps = {{style:[theme.styles.ph1,theme.styles.mh05]}}
1469
+ />
1470
+ </View>)
1471
+ }
1472
+
1473
+ });
1474
+ }
1475
+ }
1476
+ return <View testID={testID+"_ContentContainer"} style={[theme.styles.w100,theme.styles,theme.styles.justifyContentCenter,theme.styles.pt1,theme.styles.pb1,theme.styles.alignItemsCenter,!cells && theme.styles.ml1,theme.styles.mr1,cStyle]}>
1477
+ <Label testID={testID+"_Label"} splitText numberOfLines={3} textBold style={[theme.styles.w100,lStyle]}>{label}</Label>
1478
+ {cells ? <View style = {[theme.styles.w100,theme.styles.row,theme.styles.alignItemsFlexStart]}
1479
+ >{cells}</View> : null}
1480
+ </View>
1326
1481
  }
1327
1482
  isRowSelected(rowKey,rowIndex){
1328
1483
  if(isObj(rowKey)){
@@ -1344,7 +1499,7 @@ export default class CommonDatagridComponent extends AppComponent {
1344
1499
  }
1345
1500
  });
1346
1501
  Object.map(rows,(row,i)=>{
1347
- if(isObj(row)) {
1502
+ if(this.canSelectRow(row)) {
1348
1503
  const rowKey = this.getRowKey(row,i);
1349
1504
  this.selectedRowsCount++;
1350
1505
  this.selectedRows[rowKey] = row;
@@ -1626,7 +1781,7 @@ export default class CommonDatagridComponent extends AppComponent {
1626
1781
  if(this.state.data && typeof this.state.data.length ==='number'){
1627
1782
  max = max ? Math.min(max,this.state.data.length,max) : this.state.data.length;
1628
1783
  }
1629
- return max;
1784
+ return Math.max(max-this.getSectionListDataSize(),0);
1630
1785
  }
1631
1786
  canSetIsLoading(){
1632
1787
  return isObj(this.progressBarRef.current) && typeof this.progressBarRef.current.setIsLoading =='function' ? true : false;
@@ -2051,6 +2206,7 @@ CommonDatagridComponent.propTypes = {
2051
2206
  PropTypes.bool,
2052
2207
  PropTypes.object,
2053
2208
  ]),
2209
+ showActions : PropTypes.bool,//si on affichera les actions du datagrid
2054
2210
  /*** affiche ou masque les filtres */
2055
2211
  showFilters : PropTypes.bool,
2056
2212
  /*** si le pied de page sera affiché */
@@ -2168,8 +2324,11 @@ CommonDatagridComponent.propTypes = {
2168
2324
  PropTypes.arrayOf(PropTypes.object),
2169
2325
  PropTypes.objectOf(PropTypes.object),
2170
2326
  ]),
2327
+ sectionListHeaderEmptyValue : PropTypes.string, //la valeur vide par défaut à afficher dans les entêtes du table
2171
2328
  ignoreCaseOnSectionListHeader : PropTypes.bool,//si l'on ignorera la casse dans le sectionlISThEADER
2172
2329
  sectoonListHeaderUpperCase : PropTypes.bool, //si le sectionListHeader sera en majuscule
2330
+ getSectionListHeaderLabelStyle : PropTypes.func,//la fonction permettant de récupérer les styles à appliquer sur le composant label de la section header
2331
+ getSectionListHeaderContentContainerStyle : PropTypes.func, //retourne les styles à appliquer sur le contentContainer de la sectionListHeader
2173
2332
  getSectionListHeaderStyle : PropTypes.func, // la fonction permettant de récupérer les propriétés particulières à appliquer au style passé en paramètre
2174
2333
  /*** spécifie si le datagrid est groupable et si l'on utilisera les sectionList du composant FLashList pour le rendu du tableau
2175
2334
  * si une colonne n'est pas groupable alors elle ne peut pas apparaître dans les sectionList
@@ -3,9 +3,9 @@ import View from "$ecomponents/View";
3
3
  import React from "$react";
4
4
  import memoize from "$react/memoize";
5
5
  export {default as FooterItem} from "./Footer";
6
+ import {parseDecimal} from "$utils";
6
7
 
7
- export const evalSingleValue = ({data,columnDef,field,result,result2,displayLabel,onlyVisible})=>{
8
- result = defaultObj(result)
8
+ export const evalSingleValue = ({data,columnDef,field,result,withLabel,displayLabel,onlyVisible})=>{
9
9
  data = data || {}
10
10
  if(!isNonNullString(field) || !isObj(columnDef)) return result;
11
11
  onlyVisible = defaultBool(onlyVisible,true);
@@ -17,33 +17,34 @@ export const evalSingleValue = ({data,columnDef,field,result,result2,displayLabe
17
17
  if(!isDecimal(val)){
18
18
  return result;
19
19
  }
20
- if(!isObj(result[field])){
21
- let label = defaultStr(columnDef.label,columnDef.text);
22
- if(!label && displayLabel !== false) return result;
23
- result[field] = {
24
- label,
25
- visible : columnDef.visible,
26
- format : defaultStr(columnDef.format).toLowerCase()
20
+ val = parseDecimal(val.toFixed(10));
21
+ (Array.isArray(result) ? result : [result]).map((currentResult)=>{
22
+ currentResult = defaultObj(currentResult);
23
+ if(!isObj(currentResult[field])){
24
+ let label = defaultStr(columnDef.label,columnDef.text);
25
+ if(!label && displayLabel !== false && withLabel !== false) return currentResult;
26
+ currentResult[field] = {
27
+ label,
28
+ visible : columnDef.visible,
29
+ format : defaultStr(columnDef.format).toLowerCase()
30
+ }
27
31
  }
28
- }
29
- let obj = result[field];
30
- val = parseFloat(val.toFixed(10));
31
- obj.max = isDecimal(obj.max) ? Math.max(obj.max,val) : val;
32
- obj.min = isDecimal(obj.min) ? Math.min(obj.min,val) : val;
33
- obj.count = isDecimal(obj.count) ? (obj.count = obj.count +1) : 1;
34
- obj.sum = isDecimal(obj.sum) ? (parseFloat((obj.sum+val).toFixed(10))) : val;
35
- obj.average = obj.sum / obj.count;
36
- if(isObj(result2)){
37
- result2[field] = defaultObj(result2[field]);
38
- }
32
+ const obj = currentResult[field];
33
+ obj.max = isDecimal(obj.max) ? Math.max(obj.max,val) : val;
34
+ obj.min = isDecimal(obj.min) ? Math.min(obj.min,val) : val;
35
+ obj.count = isDecimal(obj.count) ? (obj.count = obj.count +1) : 1;
36
+ obj.sum = isDecimal(obj.sum) ? (parseDecimal((obj.sum+val).toFixed(10))) : val;
37
+ obj.average = obj.sum / obj.count;
38
+ return currentResult;
39
+ })
39
40
  return result;
40
41
  }
41
- export const evalValues = memoize(({data,columns,onlyVisible,displayLabel})=>{
42
+ export const evalValues = memoize(({data,columns,onlyVisible,withLabel,displayLabel})=>{
42
43
  let result = {};
43
44
  Object.map(data,(rowData,i)=>{
44
45
  if(!isObj(rowData)) return result;
45
46
  Object.map(columns,(columnDef,field)=>{
46
- result = evalSingleValue({data:rowData,columnDef,field,result,displayLabel,onlyVisible})
47
+ result = evalSingleValue({data:rowData,columnDef,field,result,withLabel,displayLabel,onlyVisible})
47
48
  })
48
49
  })
49
50
  return result;
@@ -93,4 +94,6 @@ export default function DGGridFooters (props){
93
94
  }
94
95
  })}
95
96
  </Component>
96
- }
97
+ }
98
+
99
+ export {_Footer as Footer};
@@ -4,10 +4,10 @@ export default {
4
4
  code:'fixed',icon:fixedIcon,
5
5
  label:'Tableau virtuel optimisé',
6
6
  desktop:true,
7
- title : "Les éléments de liste s'affichent dans un tableau virtuel optimisé",
7
+ tooltip : "Les éléments de liste s'affichent dans un tableau virtuel optimisé",
8
8
  },
9
9
  virtual : {code:'virtual',icon:virtualIcon,
10
10
  label:'Tableau virtuel',
11
- title : "Les éléments de liste s'affichent dans un tableau virtuel", desktop:true
11
+ tooltip : "Les éléments de liste s'affichent dans un tableau virtuel", desktop:true
12
12
  }
13
13
  }