@fto-consult/expo-ui 8.41.0 → 8.43.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.
@@ -7,9 +7,9 @@
7
7
  "@react-native-community/netinfo": "11.1.0",
8
8
  "@react-native/assets-registry": "^0.72.0",
9
9
  "react-native-get-random-values": "~1.8.0",
10
- "@react-navigation/native": "^6.1.14",
11
- "@react-navigation/native-stack": "^6.9.22",
12
- "@react-navigation/stack": "^6.3.25",
10
+ "@react-navigation/native": "^6.1.15",
11
+ "@react-navigation/native-stack": "^6.9.24",
12
+ "@react-navigation/stack": "^6.3.27",
13
13
  "@shopify/flash-list": "1.6.3",
14
14
  "expo": "^50.0.11",
15
15
  "expo-camera": "~14.0.6",
@@ -31,6 +31,6 @@
31
31
  "react-native-gesture-handler": "~2.14.0",
32
32
  "react-native-reanimated": "~3.6.2",
33
33
  "react-native-view-shot": "3.8.0",
34
- "expo-intent-launcher" : "~10.11.0"
34
+ "expo-intent-launcher": "~10.11.0"
35
35
  };
36
36
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fto-consult/expo-ui",
3
- "version": "8.41.0",
3
+ "version": "8.43.0",
4
4
  "description": "Bibliothèque de composants UI Expo,react-native",
5
5
  "scripts": {
6
6
  "clear-npx-cache": "npx clear-npx-cache",
@@ -93,8 +93,7 @@
93
93
  "sharp-cli": "^2.1.0",
94
94
  "stream-browserify": "^3.0.0",
95
95
  "tippy.js": "^6.3.7",
96
- "xlsx": "^0.18.5",
97
- "expo-intent-launcher": "~10.11.0"
96
+ "xlsx": "^0.18.5"
98
97
  },
99
98
  "devDependencies": {
100
99
  "@babel/plugin-proposal-export-namespace-from": "^7.18.9",
@@ -100,6 +100,7 @@ const Provider = ({children,getTableData,handleHelpScreen,navigation,swrConfig,a
100
100
  },
101
101
  }
102
102
  Auth.setRef(auth);
103
+ console.log("has set ref auth ",auth);
103
104
  extendFormFields(customFormFields);
104
105
  structsData = isObj(structsData)? structsData : null;
105
106
  appConfig.tablesData = tablesData;
package/src/pdf/index.js CHANGED
@@ -3,12 +3,40 @@ import Preloader from "$preloader";
3
3
  import pdfMake from "$cpdf/pdfmake";
4
4
  import notify from "$cnotify";
5
5
  import DialogProvider from "$ecomponents/Form/FormData/DialogProvider";
6
- import {isNonNullString,defaultObj,defaultStr,extendObj} from "$cutils";
6
+ import {isNonNullString,defaultObj,defaultStr,extendObj,defaultNumber,isJSON} from "$cutils";
7
7
  import session from "$session";
8
8
  import printPdfMake from "./print";
9
9
  import appConfig from "$capp/config";
10
10
  import Auth from "$cauth";
11
+ import DateLib from "$clib/date";
12
+ import crypToJS from "$clib/crypto-js";
11
13
 
14
+ export const QR_CODE_HASH_KEY_PREFIX = defaultStr(appConfig.name).replace(/\s/g, "");
15
+ export const QR_CODE_HASH_KEY = `${QR_CODE_HASH_KEY_PREFIX}-QR_CODE_HASH_KEY`;//la clé de décryptage du QRCODE
16
+
17
+
18
+ /****
19
+ génère la valeur haschée de la données d'un qrCode
20
+ */
21
+ export const hashQRCode = (data)=>{
22
+ try {
23
+ return crypToJS.encode(JSON.stringify(data),QR_CODE_HASH_KEY).toString()
24
+ } catch(Exception){
25
+ return null;
26
+ }
27
+ }
28
+
29
+ export const decryptQRCode = (hashedQRCode)=>{
30
+ return crypToJS.decode(hashedQRCode,QR_CODE_HASH_KEY);
31
+ }
32
+
33
+ export const isValidQRCode = (data)=>{
34
+ if(isJSON(data)){
35
+ data = JSON.parse(data);
36
+ }
37
+ data = defaultObj(data);
38
+ return hashQRCode(data.data) === data.hash && QR_CODE_HASH_KEY_PREFIX.toLowerCase() == defaultStr(data.provider).toLowerCase().replace(/\s/g, "");
39
+ }
12
40
 
13
41
  const {createPdf} = pdfMake;
14
42
  pdfMake.createPdf = (docDefinition,...rest)=>{
@@ -57,7 +85,7 @@ export const getFields = (config)=>{
57
85
  @paramm {multiple},
58
86
  @param {object} formDataProps, les prpops à passer au DialogProvider
59
87
  */
60
- export const getPrintSettings = ({multiple,duplicateDocOnPage,pageBreakBeforeEachDoc,sessionName,formDataProps,...rest})=>{
88
+ export const getPrintSettings = ({multiple,duplicateDocOnPage,isTableData,tableDataFields,pageBreakBeforeEachDoc,sessionName,formDataProps,...rest})=>{
61
89
  formDataProps = Object.assign({},formDataProps);
62
90
  const hasSession = isNonNullString(sessionName);
63
91
  if(hasSession){
@@ -67,11 +95,19 @@ export const getPrintSettings = ({multiple,duplicateDocOnPage,pageBreakBeforeEac
67
95
  }
68
96
  const sessionData = hasSession ? defaultObj(session.get(sessionName)) : {};
69
97
  const config = {...sessionData,...defaultObj(formDataProps.data)};
98
+ const tbFields = {}, tbPrimaryKeyFields = [];
99
+ Object.map(tableDataFields,(field,index)=>{
100
+ if(!isObj(field)) return;
101
+ tbFields[index] = field;
102
+ if(!!field.primaryKey){
103
+ tbPrimaryKeyFields.push(index);
104
+ }
105
+ });
70
106
  const fields = extendObj(true,{},formDataProps.fields,{
71
107
  duplicateDocOnPage : duplicateDocOnPage !== false ? {
72
108
  text :'Dupliquer le(s) document(s)',
73
109
  type : 'switch',
74
- defaultValue : 0,
110
+ defaultValue : 1,
75
111
  onValidate : ({value,context}) =>{
76
112
  if(context){
77
113
  const pageBreakBeforeEachDoc = context.getField("pageBreakBeforeEachDoc");
@@ -124,6 +160,49 @@ export const getPrintSettings = ({multiple,duplicateDocOnPage,pageBreakBeforeEac
124
160
  return v;
125
161
  }
126
162
  } : undefined,
163
+ ...(isTableData && tbPrimaryKeyFields.length ?{
164
+ printQRCode : {
165
+ type : "switch",
166
+ label : "Imprimer un QR Code",
167
+ tooltip : "Cochez la case pour inclure un QR Code dans la données imprimée",
168
+ defaultValue : 0,
169
+ },
170
+ qrCodeFields : {
171
+ type : "select",
172
+ label : "Champs à inclure dans le QR Code",
173
+ multiple : true,
174
+ items : tbFields,
175
+ filter : ({item,index})=>isObj(item),
176
+ itemValue : ({item,index})=>index,
177
+ defaultValue : tbPrimaryKeyFields,
178
+ onValidatorValid : ({value})=>{
179
+ if(!Array.isArray(value) || !value.length) return true;
180
+ for(let i in tbPrimaryKeyFields){
181
+ const p = tbPrimaryKeyFields[i];
182
+ if(!value.includes(p)){
183
+ return `Le champ [${p}] en temps que clé primaire doit figurer parmis les champs à imprimer dans le QR Code.`;
184
+ }
185
+ }
186
+ return true;
187
+ },
188
+ renderItem : ({item,index})=>{
189
+ return `[${index}] ${defaultStr(item.label,item.text)}`;
190
+ }
191
+ },
192
+ qrCodeAlignmentPosition : {
193
+ type : "select",
194
+ defaultValue : "center",
195
+ label : "Position du QR Code",
196
+ multiple : false,
197
+ items : [{code:"left",label:"A gauche"},{code:"center",label:"Au centre"},{code:"right",label:"A droite"}]
198
+ },
199
+ qrCodeFitSize : {
200
+ type :"number",
201
+ defaultValue : 150,
202
+ label : "Taille du QR Code",
203
+ validType : "numberGreaterThanOrEquals[120]"
204
+ },
205
+ }:{})
127
206
  },getFields(formDataProps.data))
128
207
  return new Promise((resolve,reject)=>{
129
208
  return DialogProvider.open({
@@ -157,6 +236,7 @@ export const getPrintSettings = ({multiple,duplicateDocOnPage,pageBreakBeforeEac
157
236
  @param {object<{
158
237
  table|tableName {string}, le nom de la table data à utilser pour l'impression
159
238
  print {funtion}, la fonction à utiliser pour faire l'impression, si cette fonction n'est pas définie, alors la table data lié à la table doit l'implémenter dans l'option print
239
+ perm {function|string}, la fonction permettant de vérifier l'accès à la fonction d'impression par l'utilisateur
160
240
  }>}
161
241
  @return Promise
162
242
  */
@@ -172,17 +252,49 @@ export function printTableData(data,options){
172
252
  if(!tablePrint){
173
253
  return Promise.reject({message : `La fonction d'impression n'est pas supportée par la table [${tableText}]`})
174
254
  }
175
- if(!Auth.isTableDataAllowed({table,action:'print'})){
255
+ if(typeof options.perm =="function"){
256
+ if(!options.perm({table,tableObj})) {
257
+ return Promise.reject({message:'Vous n\'etes pas autorisé à imprimer ce type de document'});
258
+ }
259
+ } else if(isNonNullString(options.perm)){
260
+ if(!Auth.isAllowedFromString(options.perm)){
261
+ return Promise.reject({message:'Vous n\'etes pas autorisé à imprimer ce type de document'});
262
+ }
263
+ } else if(!Auth.isTableDataAllowed({table,action:'print'})){
176
264
  return Promise.reject({message:'Vous n\'etes pas autorisé à imprimer ce type de document'});
177
265
  }
178
266
  const printOptions = typeof tableObj.printOptions =="function"? tableObj.printOptions({...options,table,data}) : tableObj.printOptions;
179
267
  return print(data,{
180
268
  getSettings : (options)=>{
181
- return getPrintSettings(extendObj(true,{},{sessionName:`print-${table}`},options,printOptions)).then(({data})=>{
269
+ return getPrintSettings(extendObj(true,{},{sessionName:`print-${table}`,isTableData:true,tableDataFields:defaultObj(options.tableDataFields,tableObj.printableFields,tableObj.fields)},options,printOptions)).then(({data})=>{
182
270
  return data;
183
271
  });
184
272
  },
185
- print : tablePrint,
273
+ print : (data,...rest)=>{
274
+ return Promise.resolve(tablePrint(data,...rest)).then((result)=>{
275
+ if(!!data?.printQRCode && Array.isArray(data?.qrCodeFields) && data.qrCodeFields.length && isObj(result) && Array.isArray(result.content) && isObj(data?.data)){
276
+ const qrCodeFields = data.qrCodeFields;
277
+ const printingData = data.data;
278
+ const qrCodeAlignmentPosition = defaultStr(data.qrCodeAlignmentPosition,"center");
279
+ const qrData = {};
280
+ let hasQRData = false;
281
+ qrCodeFields.map((f)=>{
282
+ if(f in printingData){
283
+ qrData[f] = ["number","boolean"].includes(typeof printingData[f])? printingData[f] : JSON.stringify(printingData[f]);
284
+ hasQRData = true;
285
+ }
286
+ });
287
+ if(hasQRData){
288
+ const uEmail = Auth.getUserEmail();
289
+ const pseudo = Auth.getUserPseudo();
290
+ const fullName = Auth.getUserFullName() || pseudo || Auth.getLoggedUserCode();
291
+ const printBy = isNonNullString(fullName)? (`${fullName}${uEmail?`[${uEmail}]`:""}`) : "";
292
+ result.content.push({ qr: JSON.stringify({data:qrData,hash:hashQRCode(qrData),provider:defaultStr(appConfig.name).replace(/\s/g, ""),printBy,printDate:new Date().toFormat(DateLib.defaultDateTimeFormat),tableName:table}),margin:[0,8,0,5], fit: defaultNumber(data.qrCodeFitSize,150), alignment: qrCodeAlignmentPosition})
293
+ }
294
+ }
295
+ return result;
296
+ });
297
+ },
186
298
  ...Object.assign({},options),
187
299
  });
188
300
  }
@@ -1,6 +1,6 @@
1
1
  module.exports = {
2
2
  "@fto-consult/expo-ui": {
3
- "version": "8.39.0",
3
+ "version": "8.41.0",
4
4
  "url": "https://github.com/borispipo/expo-ui#readme",
5
5
  "license": "ISC"
6
6
  },
@@ -50,17 +50,17 @@ module.exports = {
50
50
  "license": "MIT"
51
51
  },
52
52
  "@react-navigation/native": {
53
- "version": "6.1.14",
53
+ "version": "6.1.15",
54
54
  "url": "https://reactnavigation.org",
55
55
  "license": "MIT"
56
56
  },
57
57
  "@react-navigation/native-stack": {
58
- "version": "6.9.22",
58
+ "version": "6.9.24",
59
59
  "url": "https://github.com/software-mansion/react-native-screens#readme",
60
60
  "license": "MIT"
61
61
  },
62
62
  "@react-navigation/stack": {
63
- "version": "6.3.25",
63
+ "version": "6.3.27",
64
64
  "url": "https://reactnavigation.org/docs/stack-navigator/",
65
65
  "license": "MIT"
66
66
  },
@@ -104,6 +104,11 @@ module.exports = {
104
104
  "url": "https://docs.expo.dev/versions/latest/sdk/imagepicker/",
105
105
  "license": "MIT"
106
106
  },
107
+ "expo-intent-launcher": {
108
+ "version": "10.11.0",
109
+ "url": "https://docs.expo.dev/versions/latest/sdk/intent-launcher/",
110
+ "license": "MIT"
111
+ },
107
112
  "expo-linking": {
108
113
  "version": "6.2.2",
109
114
  "url": "https://docs.expo.dev/versions/latest/sdk/linking",