@fto-consult/expo-ui 2.34.3 → 2.35.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fto-consult/expo-ui",
3
- "version": "2.34.3",
3
+ "version": "2.35.0",
4
4
  "description": "Bibliothèque de composants UI Expo,react-native",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -155,7 +155,7 @@ export const footerFieldName = "dgrid-fters-fields";
155
155
 
156
156
 
157
157
  /*****
158
- * Pour spécifier qu'un champ du datagrid n'existe pas en bd il s'uffit de suffixer le nom du champ par le suffix : "FoundInDB" et de renseigner false comme valeur
158
+ * Pour spécifier qu'un champ du datagrid n'existe pas en bd il s'ufit de suffixer le nom du champ par le suffix : "FoundInDB" et de renseigner false comme valeur
159
159
  de l'objet rowData de cette propriété
160
160
  */
161
161
  export default class CommonDatagridComponent extends AppComponent {
@@ -166,6 +166,9 @@ export default class CommonDatagridComponent extends AppComponent {
166
166
  let {
167
167
  data,
168
168
  selectedRows,
169
+ chartAllowedPerm,
170
+ exportToPDFAllowedPerm,
171
+ exportToExcelAllowedPerm,
169
172
  ...rest
170
173
  } = props;
171
174
  if(this.bindResizeEvents()){
@@ -196,15 +199,27 @@ export default class CommonDatagridComponent extends AppComponent {
196
199
  });
197
200
  const disTypes = {};
198
201
  let hasFoundDisplayTypes = false;
202
+ const perm = isNonNullString(chartAllowedPerm)? Auth.isAllowedFromStr(chartAllowedPerm) : true;
203
+ const ePDFIsAllowed = isNonNullString(exportToPDFAllowedPerm)? Auth.isAllowedFromStr(exportToPDFAllowedPerm) : true;
204
+ const eExcelISAllowed = isNonNullString(exportToExcelAllowedPerm)? Auth.isAllowedFromStr(exportToExcelAllowedPerm) : true;
199
205
  Object.map(this.props.displayTypes,(dType,v)=>{
200
206
  if(isNonNullString(dType)){
201
207
  dType = dType.toLowerCase().trim();
202
208
  if(displayTypes[dType]){
209
+ const dp = displayTypes[dType];
210
+ if(dp.isChart && !perm){
211
+ return;
212
+ }
213
+ hasFoundDisplayTypes = true;
203
214
  disTypes[dType] = Object.clone(displayTypes[dType]);
204
215
  }
205
- hasFoundDisplayTypes = true;
206
216
  }
207
217
  });
218
+ const allowedDisplayTypes = {};
219
+ Object.map(displayTypes,(t,i)=>{
220
+ if(t.isChart && !perm) return;
221
+ allowedDisplayTypes[i] = Object.clone(t);
222
+ })
208
223
  Object.defineProperties(this,{
209
224
  layoutRef : {
210
225
  value : React.createRef(null),
@@ -230,6 +245,9 @@ export default class CommonDatagridComponent extends AppComponent {
230
245
  isLoadingRef : {
231
246
  value : {current:false}
232
247
  },
248
+ isChartAllowed : {value : perm},
249
+ isExcellExportAllowed : {value:eExcelISAllowed},
250
+ isPDFExportAllowed : {value: ePDFIsAllowed},
233
251
  currentFilteringColumns : {value:{}},
234
252
  emptySectionListHeaderValue : {value : uniqid("empty-section-list-header-val").toUpperCase()},
235
253
  getSectionListHeaderProp : {value : typeof this.props.getSectionListHeader =='function'? this.props.getSectionListHeader : undefined},
@@ -242,7 +260,7 @@ export default class CommonDatagridComponent extends AppComponent {
242
260
  ///la liste des fonctions d'aggregations supportées
243
261
  aggregatorFunctions : {value : extendAggreagatorFunctions(this.props.aggregatorFunctions)},
244
262
  ///les types d'affichage
245
- displayTypes : {value : hasFoundDisplayTypes ? disTypes : Object.clone(displayTypes)},
263
+ displayTypes : {value : hasFoundDisplayTypes ? disTypes : allowedDisplayTypes},
246
264
  dateFields : {value : {}},
247
265
  sectionListColumnsSize : {value : {current:0}}, //la taille du nombre d'éléments de section dans les colonnes
248
266
  chartRef : {value : {current:null}},
@@ -372,6 +390,12 @@ export default class CommonDatagridComponent extends AppComponent {
372
390
  }
373
391
  return this.state.sectionListColumns;
374
392
  }
393
+ canExportToPDF(){
394
+ return this.isPDFExportAllowed;
395
+ }
396
+ canExportToExcel (){
397
+ return this.isExcellExportAllowed;
398
+ }
375
399
  bindResizeEvents(){
376
400
  return false;
377
401
  }
@@ -719,7 +743,7 @@ export default class CommonDatagridComponent extends AppComponent {
719
743
  if(header.type.contains("date")){
720
744
  this.dateFields[header.field] = header;
721
745
  }
722
- /**** pour ignorer une colonne du datagrid, il suffit de passer le paramètre datagrid à false */
746
+ /**** pour ignorer une colonne du datagrid, il sufit de passer le paramètre datagrid à false */
723
747
  if(!isNonNullString(header.field) || header.datagrid === false) {
724
748
  return;
725
749
  }
@@ -2094,6 +2118,10 @@ export default class CommonDatagridComponent extends AppComponent {
2094
2118
  let totalWidths = 0;
2095
2119
  let columnIndex = 0,visibleColumnIndex=0;
2096
2120
  this.sectionListColumnsSize.current = 0;
2121
+ /*** la props widht de la colonne peut être en pourcentage
2122
+ * l'on peut également définir la valeur minWidth en entier qui représentera la longuer minimale du champ
2123
+ * la props fitWidth permet de dire que le champ devra occuper l'espace restant sur la page
2124
+ */
2097
2125
  Object.map(columns,(header,headerIndex) => {
2098
2126
  let {
2099
2127
  field,
@@ -2115,6 +2143,9 @@ export default class CommonDatagridComponent extends AppComponent {
2115
2143
 
2116
2144
  const type = defaultStr(header.jsType,header.type,"text").toLowerCase();
2117
2145
  sortType = defaultStr(sortType,type).toLowerCase();
2146
+ if(typeof width =='string' && width.contains("%")){
2147
+ width = ((parseFloat(width.replaceAll(" ","").split('%')[0].trim())|0)*windowWidth)/100;
2148
+ }
2118
2149
  width = defaultDecimal(width);
2119
2150
  if(width <COLUMN_WIDTH/2){
2120
2151
  width = COLUMN_WIDTH;
@@ -2129,6 +2160,9 @@ export default class CommonDatagridComponent extends AppComponent {
2129
2160
  } else if(type =="select_country" || type =='selectcountry'){
2130
2161
  width = Math.max(width,90);
2131
2162
  }
2163
+ if(typeof restCol.minWidth =='number'){
2164
+ width = Math.max(width,minWidth);
2165
+ }
2132
2166
  totalWidths +=width;
2133
2167
  widths[header.field] = width;
2134
2168
  const colProps = {id,key}
@@ -2139,6 +2173,7 @@ export default class CommonDatagridComponent extends AppComponent {
2139
2173
  }
2140
2174
  const title = header.text = header.text || header.label || header.title||header.field
2141
2175
  visibleColumnsNames[header.field] = visible ? true : false;
2176
+
2142
2177
  visibleColumns.push({
2143
2178
  onPress : ()=>{
2144
2179
  setTimeout(() => {
@@ -3522,6 +3557,12 @@ CommonDatagridComponent.propTypes = {
3522
3557
  /**** les series à utiliser pour l'affichage des données lorsque les colonnes sont groupées, ie les montant de totalisation sont utilisés */
3523
3558
  sectionListHeadersSeries : PropTypes.arrayOf(PropTypes.string),
3524
3559
  }),
3560
+ /*** la permission autorisée pour l'export en pdf */
3561
+ exportToPDFAllowedPerm : PropTypes.string,
3562
+ /*** la permission autorisée pour l'export en excel*/
3563
+ exportToExcelAllowedPerm : PropTypes.string,
3564
+ /*** la permission que doit avoir l'utilisateur pour pouvoir visualiser les graphes à partir du diagrame */
3565
+ chartAllowedPerm : PropTypes.string,
3525
3566
  displayType : chartDisplayType,
3526
3567
  /*** les types d'afichates supportés par l'application */
3527
3568
  displayTypes : PropTypes.arrayOf(chartDisplayType),
@@ -34,6 +34,15 @@ const TableDataSelectField = React.forwardRef((_props,ref)=>{
34
34
  }
35
35
  fKeyTable = defaultObj(fKeyTable);
36
36
  foreignKeyTable = defaultStr(fKeyTable.tableName,fKeyTable.table,foreignKeyTable).trim().toUpperCase();
37
+ const sortColumn = defaultStr(fKeyTable.defaultSortColumn);
38
+ const sortDir = defaultStr(fKeyTable.defaultSortOrder).toLowerCase().trim();
39
+ const sort = {};
40
+ if(sortColumn){
41
+ sort.column = sortColumn;
42
+ if(sortDir =='asc' || sortDir =='desc'){
43
+ sort.dir = sortDir;
44
+ }
45
+ }
37
46
  const isMounted = React.useIsMounted();
38
47
  const showAdd = isFilter || !foreignKeyTable ? false : React.useRef(Auth.isTableDataAllowed({foreignKeyTable,action:'create'}) ? defaultVal(props.showAdd,props.showAddBtn,true) : false).current;
39
48
  const [state,setState] = React.useState({
@@ -44,6 +53,9 @@ const TableDataSelectField = React.forwardRef((_props,ref)=>{
44
53
  const cFetch = typeof customFetchItem =='function' && customFetchItem;
45
54
  const fetchItems = (opts)=>{
46
55
  opts.showError = false;
56
+ if(sortColumn){
57
+ opts.sort = sort;
58
+ }
47
59
  if(cFetch) return cFetch(queryPath,opts);
48
60
  if(queryPath){
49
61
  return fetch(queryPath,opts);
@@ -109,6 +109,7 @@ export const getFilterComponentProps = (_props)=>{
109
109
  } else if(isNonNullString(props.foreignKeyColumn) && isNonNullString(props.foreignKeyTable)) {
110
110
  component = Fields.SelectTableData;
111
111
  props.multiple = true;
112
+ type = "select";
112
113
  }else {
113
114
  const tt = type.replaceAll("_","").toLowerCase();
114
115
  if(React.isComponent(componentTypes[tt])){
@@ -18,7 +18,7 @@ import fetch from "$capi/fetch";
18
18
  import Auth from "$auth";
19
19
  import Icon from "$ecomponents/Icon";
20
20
 
21
- export default function DatabaseStatisticContainer ({dashboardProps,fetchDataProps,table,fetchCount,index,testID,title,icon,onPress:customOnPress,columns,fetchData,withDashboard,...props}){
21
+ export default function DatabaseStatisticContainer ({dashboardProps,onRefreshAll,fetchDataProps,table,fetchCount,index,testID,title,icon,onPress:customOnPress,columns,fetchData,withDashboard,...props}){
22
22
  dashboardProps = defaultObj(dashboardProps);
23
23
  const [count,setCount] = React.useState(0);
24
24
  const datagridRef = React.useRef(null);
@@ -44,6 +44,11 @@ export default function DatabaseStatisticContainer ({dashboardProps,fetchDataPro
44
44
  }
45
45
  const refreshingRef = React.useRef(null);
46
46
  const isMounted = React.useIsMounted();
47
+ const onRefreshAllItem = typeof onRefreshAll =='function'? {
48
+ text : "Tout actualiser",
49
+ onPress : onRefreshAll,
50
+ icon : "refresh-circle"
51
+ } : {}
47
52
 
48
53
  const [isLoading,setIsLoading] = React.useState(withDashboard?false:true);
49
54
  const refresh = ()=>{
@@ -148,7 +153,7 @@ export default function DatabaseStatisticContainer ({dashboardProps,fetchDataPro
148
153
  </View>
149
154
  <Menu
150
155
  testID={testID+"_Menu"}
151
- items = {context.renderMenu()}
156
+ items = {[...context.renderMenu(),onRefreshAllItem]}
152
157
  anchor = {(p)=><Pressable {...p} style={[theme.styles.pl1]} testID={testID+"_MenuAnchor"}>
153
158
  <Label
154
159
  textCenter
@@ -177,7 +182,8 @@ export default function DatabaseStatisticContainer ({dashboardProps,fetchDataPro
177
182
  icon : "refresh",
178
183
  onPress : refresh,
179
184
  text : "Actualiser"
180
- }
185
+ },
186
+ onRefreshAllItem,
181
187
  ]}
182
188
  anchor = {(p)=><Avatar suffix={index} {...aProps} {...p} icon= {icon} size={40} label={title}/>}
183
189
  />
@@ -5,6 +5,7 @@ import React from "$react";
5
5
  import DatabaseStatistic from "./DatabaseStatistic";
6
6
  import theme from "$theme";
7
7
  import PropTypes from "prop-types";
8
+ import Auth from "$cauth";
8
9
 
9
10
  export const title = 'Statistiques en BD';
10
11
  export default function DatabaseStatisticScreen ({withScreen,fetchDataProps,tableFilter,fetchCount,fetchData,title:customTitle,contentProps,containerProps,tables,Component,...props}){
@@ -12,6 +13,7 @@ export default function DatabaseStatisticScreen ({withScreen,fetchDataProps,tabl
12
13
  containerProps = defaultObj(containerProps);
13
14
  const title = containerProps.title = defaultStr(containerProps.title,DatabaseStatisticScreen.title);
14
15
  contentProps = defaultObj(contentProps);
16
+ const forceRender = React.useForceRender();
15
17
  if(Component == Cell){
16
18
  containerProps.desktopSize = defaultNumber(containerProps.desktopSize,12);
17
19
  containerProps.tabletSize = defaultNumber(containerProps.tabletSize,8);
@@ -28,6 +30,8 @@ export default function DatabaseStatisticScreen ({withScreen,fetchDataProps,tabl
28
30
  table = t;
29
31
  }
30
32
  if(table.databaseStatistic === false || table.databaseStatistics === false) return null;
33
+ const chartAllowedPerm = defaultStr(table.chartAllowedPerm);
34
+ if(chartAllowedPerm && !Auth.isAllowedFromStr(chartAllowedPerm || !Auth.isTableDataAllowed({table:tableName}))) return null;
31
35
  content.push(<Cell elevation = {5} withSurface mobileSize={12} desktopSize={3} tabletSize={4} {...contentProps} key = {index} >
32
36
  <DatabaseStatistic
33
37
  icon = {table.icon}