tango-app-api-trax 3.9.33 → 3.9.35
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/index.js +2 -1
- package/package.json +1 -1
- package/src/controllers/internalTrax.controller.js +134 -90
- package/src/controllers/mobileTrax.controller.js +69 -29
- package/src/controllers/trax.controller.js +7 -1
- package/src/controllers/traxDashboard.controllers.js +63 -54
- package/src/hbs/flag.hbs +1 -1
- package/src/hbs/login-otp.hbs +943 -943
- package/src/hbs/template.hbs +7 -0
- package/src/hbs/visit-checklist.hbs +49 -87
- package/src/logging/activityLogFlusher.js +59 -0
- package/src/logging/activityLogMiddleware.js +45 -0
- package/src/logging/activityLogStore.js +91 -0
- package/src/logging/compressBatches.js +83 -0
- package/src/logging/config.js +24 -0
- package/src/logging/createLoggableService.js +46 -0
- package/src/logging/logExternalCall.js +37 -0
- package/src/services/app.service.js +15 -9
- package/src/services/approver.service.js +23 -15
- package/src/services/authentication.service.js +9 -3
- package/src/services/camera.service.js +19 -13
- package/src/services/checklist.service.js +35 -27
- package/src/services/checklistAssign.service.js +43 -38
- package/src/services/checklistQuestion.service.js +39 -34
- package/src/services/checklistlog.service.js +39 -34
- package/src/services/clientRequest.service.js +9 -2
- package/src/services/clients.services.js +23 -18
- package/src/services/cluster.service.js +31 -23
- package/src/services/domain.service.js +23 -18
- package/src/services/download.services.js +35 -25
- package/src/services/group.service.js +23 -17
- package/src/services/lenskartEmployeeMapping.service.js +15 -10
- package/src/services/locus.service.js +35 -28
- package/src/services/notification.service.js +35 -26
- package/src/services/otp.service.js +20 -13
- package/src/services/planogram.service.js +9 -2
- package/src/services/processedTaskConfig.service.js +35 -27
- package/src/services/processedTaskList.service.js +32 -26
- package/src/services/processedchecklist.services.js +55 -47
- package/src/services/processedchecklistconfig.services.js +39 -34
- package/src/services/recurringFlagTracker.service.js +39 -32
- package/src/services/runAIFeatures.services.js +32 -27
- package/src/services/runAIRequest.services.js +43 -38
- package/src/services/store.service.js +32 -27
- package/src/services/tagging.service.js +9 -2
- package/src/services/taskConfig.service.js +35 -27
- package/src/services/teams.service.js +35 -24
- package/src/services/ticket.service.js +15 -10
- package/src/services/user.service.js +27 -20
- package/src/services/userAssignedstores.service.js +12 -5
- package/src/utils/visitChecklistPdf.utils.js +192 -16
|
@@ -180,11 +180,21 @@ function buildQuestionAnswerEntries( question ) {
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
const validationImage = flattenImageRefs( userAnswer?.validationImage );
|
|
183
|
+
// Videos captured alongside 'Capture Multiple Image with description' validation (no runAI; shown as links).
|
|
184
|
+
const validationVideo = flattenImageRefs( userAnswer?.validationVideo );
|
|
185
|
+
|
|
186
|
+
const referenceImage = userAnswer?.referenceImage || matchedAnswer?.referenceImage || '';
|
|
187
|
+
// Left column shows a reference image only for non-image/video, non-multipleImage answer types.
|
|
188
|
+
// When there is no reference image, uploaded/validation media is rendered on the left instead of the right.
|
|
189
|
+
const hasReferenceImage = question?.answerType !== 'image/video' &&
|
|
190
|
+
question?.answerType !== 'multipleImage' &&
|
|
191
|
+
Boolean( referenceImage || multiReferenceImage.length );
|
|
183
192
|
|
|
184
193
|
return {
|
|
185
194
|
answer: userAnswer?.answer || '',
|
|
186
195
|
answerType: getMediaDisplayType( question?.answerType, userAnswer ),
|
|
187
|
-
referenceImage
|
|
196
|
+
referenceImage,
|
|
197
|
+
hasReferenceImage,
|
|
188
198
|
multiReferenceImage,
|
|
189
199
|
remarks: userAnswer?.remarks || '',
|
|
190
200
|
sopFlag: userAnswer?.sopFlag ?? matchedAnswer?.sopFlag ?? false,
|
|
@@ -192,12 +202,93 @@ function buildQuestionAnswerEntries( question ) {
|
|
|
192
202
|
validationType,
|
|
193
203
|
validationAnswer,
|
|
194
204
|
validationImage,
|
|
205
|
+
validationVideo,
|
|
195
206
|
validationDisplayType: getValidationDisplayType( validationType ),
|
|
196
207
|
};
|
|
197
208
|
} );
|
|
198
209
|
}
|
|
199
210
|
|
|
200
211
|
|
|
212
|
+
/**
|
|
213
|
+
* Flattens a question's user answers into one ordered, deduped image list for the
|
|
214
|
+
* 2-per-row answer media grid. Order: reference images first, then uploaded images,
|
|
215
|
+
* then validation images. Videos are shown as links elsewhere, so only images are
|
|
216
|
+
* collected here. When a question has no reference image, the uploaded images simply
|
|
217
|
+
* fill the grid from the start (taking the reference slot).
|
|
218
|
+
* @param {Array} userAnswers entries produced by buildQuestionAnswerEntries
|
|
219
|
+
* @return {Array} list of { type, label, url } media items in render order
|
|
220
|
+
*/
|
|
221
|
+
function buildQuestionMediaItems( userAnswers = [] ) {
|
|
222
|
+
const items = [];
|
|
223
|
+
const seen = new Set();
|
|
224
|
+
|
|
225
|
+
const push = ( type, label, url ) => {
|
|
226
|
+
if ( !url || typeof url !== 'string' ) return;
|
|
227
|
+
if ( seen.has( url ) ) return;
|
|
228
|
+
seen.add( url );
|
|
229
|
+
items.push( { type, label, url } );
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
// 1. Reference images first (deduped, so a single shared reference shows once).
|
|
233
|
+
userAnswers.forEach( ( ua ) => {
|
|
234
|
+
if ( Array.isArray( ua.multiReferenceImage ) && ua.multiReferenceImage.length ) {
|
|
235
|
+
ua.multiReferenceImage.forEach( ( url ) => push( 'reference', 'Reference Image', url ) );
|
|
236
|
+
} else if ( ua.referenceImage ) {
|
|
237
|
+
push( 'reference', 'Reference Image', ua.referenceImage );
|
|
238
|
+
}
|
|
239
|
+
} );
|
|
240
|
+
|
|
241
|
+
// 2. Uploaded images.
|
|
242
|
+
userAnswers.forEach( ( ua ) => {
|
|
243
|
+
if ( ua.answerType === 'image' && ua.answer ) {
|
|
244
|
+
push( 'uploaded', 'Uploaded Image', ua.answer );
|
|
245
|
+
}
|
|
246
|
+
} );
|
|
247
|
+
|
|
248
|
+
// 3. Validation images (single 'Capture Image' and multi 'Capture Multiple Image').
|
|
249
|
+
userAnswers.forEach( ( ua ) => {
|
|
250
|
+
if ( !ua.validation ) return;
|
|
251
|
+
|
|
252
|
+
if ( ua.validationDisplayType === 'image' && ua.validationAnswer ) {
|
|
253
|
+
push( 'validation', 'Validation Image', ua.validationAnswer );
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if ( ua.validationDisplayType === 'multiImage' && Array.isArray( ua.validationImage ) ) {
|
|
257
|
+
ua.validationImage.forEach( ( url ) => push( 'validation', 'Validation Image', url ) );
|
|
258
|
+
}
|
|
259
|
+
} );
|
|
260
|
+
|
|
261
|
+
return items;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Extracts every 'Matched/Not Matched' value from a userAnswer's runAIData.
|
|
267
|
+
* Handles both shapes:
|
|
268
|
+
* - [ { answerImage, results: [ { featureName, value } ] } ] (per-image nested)
|
|
269
|
+
* - [ { featureName, value } ] (flat)
|
|
270
|
+
* @param {Array} runAIData
|
|
271
|
+
* @return {string[]} list of 'True' / 'False' values (in source order)
|
|
272
|
+
*/
|
|
273
|
+
function getRunAIMatchValues( runAIData ) {
|
|
274
|
+
if ( !Array.isArray( runAIData ) ) return [];
|
|
275
|
+
|
|
276
|
+
const values = [];
|
|
277
|
+
|
|
278
|
+
runAIData.forEach( ( item ) => {
|
|
279
|
+
if ( Array.isArray( item?.results ) ) {
|
|
280
|
+
item.results.forEach( ( res ) => {
|
|
281
|
+
if ( res?.featureName === 'Matched/Not Matched' ) values.push( res.value );
|
|
282
|
+
} );
|
|
283
|
+
} else if ( item?.featureName === 'Matched/Not Matched' ) {
|
|
284
|
+
values.push( item.value );
|
|
285
|
+
}
|
|
286
|
+
} );
|
|
287
|
+
|
|
288
|
+
return values;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
|
|
201
292
|
/**
|
|
202
293
|
|
|
203
294
|
* Map section array { sectionName, questions[] } (view API or processed checklist) to scores / template sections.
|
|
@@ -219,6 +310,8 @@ function mapSectionsFromQuestionAnswer( questionAnswer ) {
|
|
|
219
310
|
|
|
220
311
|
const flags = [];
|
|
221
312
|
|
|
313
|
+
let hasSopFlag = false;
|
|
314
|
+
|
|
222
315
|
|
|
223
316
|
( questionAnswer || [] ).forEach( ( section, sectionIdx ) => {
|
|
224
317
|
let sectionScore = 0;
|
|
@@ -240,6 +333,10 @@ function mapSectionsFromQuestionAnswer( questionAnswer ) {
|
|
|
240
333
|
|
|
241
334
|
const ua = userAnswersWithRef[0];
|
|
242
335
|
|
|
336
|
+
if ( !hasSopFlag && userAnswersWithRef.some( ( entry ) => entry.sopFlag === true ) ) {
|
|
337
|
+
hasSopFlag = true;
|
|
338
|
+
}
|
|
339
|
+
|
|
243
340
|
|
|
244
341
|
const max = q.compliance ? Math.max( ...q?.answers.map( ( o ) => o?.complianceScore ?? Math.max( o?.matchedCount ?? 0, o?.notMatchedCount ?? 0 ) ) ) : 0;
|
|
245
342
|
|
|
@@ -247,14 +344,18 @@ function mapSectionsFromQuestionAnswer( questionAnswer ) {
|
|
|
247
344
|
let score = q.compliance ? Math.max( ...q?.userAnswer?.map( ( o ) => o?.complianceScore ?? 0 ) ) : 0;
|
|
248
345
|
|
|
249
346
|
|
|
250
|
-
if ( q.answerType
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
347
|
+
if ( q.compliance && ( q.answerType === 'image' || q.answerType === 'image/video' ) ) {
|
|
348
|
+
// image/video questions mix image + video entries in userAnswer, so only score the images.
|
|
349
|
+
const imageAnswers = q.answerType === 'image/video' ?
|
|
350
|
+
( q.userAnswer || [] ).filter( ( ua ) => ua?.answerType === 'image' ) :
|
|
351
|
+
( q.userAnswer || [] );
|
|
352
|
+
|
|
353
|
+
const matchValues = imageAnswers.flatMap( ( ua ) => getRunAIMatchValues( ua?.runAIData ) );
|
|
354
|
+
|
|
355
|
+
if ( matchValues.length ) {
|
|
356
|
+
// All images must be matched ('True'); if any one is not, treat as not matched.
|
|
357
|
+
const allMatched = matchValues.every( ( value ) => value === 'True' );
|
|
358
|
+
score = allMatched ? ( q?.answers?.[0]?.matchedCount ?? 0 ) : ( q?.answers?.[0]?.notMatchedCount ?? 0 );
|
|
258
359
|
}
|
|
259
360
|
}
|
|
260
361
|
|
|
@@ -316,6 +417,8 @@ function mapSectionsFromQuestionAnswer( questionAnswer ) {
|
|
|
316
417
|
|
|
317
418
|
answerDisplay: isYes ? 'Yes' : ( isNo ? 'No' : ( answerText && answerText.startsWith( 'http' ) ? 'Image' : ( answerText || '—' ) ) ),
|
|
318
419
|
|
|
420
|
+
mediaItems: buildQuestionMediaItems( userAnswersWithRef ),
|
|
421
|
+
|
|
319
422
|
userAnswer: userAnswersWithRef.length ? userAnswersWithRef : [ {
|
|
320
423
|
answer: '',
|
|
321
424
|
answerType: 'text',
|
|
@@ -373,7 +476,7 @@ function mapSectionsFromQuestionAnswer( questionAnswer ) {
|
|
|
373
476
|
const numQuestions = questionAnswer.reduce( ( sum, s ) => sum + ( s.questions?.length || 0 ), 0 );
|
|
374
477
|
|
|
375
478
|
|
|
376
|
-
return { totalScore, maxScore, sectionInsights, questionAnswers, flags, numQuestions };
|
|
479
|
+
return { totalScore, maxScore, sectionInsights, questionAnswers, flags, numQuestions, hasSopFlag };
|
|
377
480
|
}
|
|
378
481
|
|
|
379
482
|
|
|
@@ -395,7 +498,7 @@ export function buildVisitChecklistTemplateDataFromProcessed( processedDoc, bran
|
|
|
395
498
|
|
|
396
499
|
const {
|
|
397
500
|
|
|
398
|
-
totalScore, maxScore, sectionInsights, questionAnswers, flags, numQuestions,
|
|
501
|
+
totalScore, maxScore, sectionInsights, questionAnswers, flags, numQuestions, hasSopFlag,
|
|
399
502
|
|
|
400
503
|
} = mapSectionsFromQuestionAnswer( questionAnswer );
|
|
401
504
|
|
|
@@ -481,6 +584,9 @@ export function buildVisitChecklistTemplateDataFromProcessed( processedDoc, bran
|
|
|
481
584
|
|
|
482
585
|
let referenceId = doc.coverage == 'store' ? doc?.storeName : doc?.userName;
|
|
483
586
|
|
|
587
|
+
const userImage = doc.userImage || '';
|
|
588
|
+
const userSignature = doc.userSignature || '';
|
|
589
|
+
|
|
484
590
|
return {
|
|
485
591
|
|
|
486
592
|
|
|
@@ -506,12 +612,22 @@ export function buildVisitChecklistTemplateDataFromProcessed( processedDoc, bran
|
|
|
506
612
|
|
|
507
613
|
numFlags: typeof doc.questionFlag === 'number' ? doc.questionFlag : flags.length,
|
|
508
614
|
|
|
509
|
-
|
|
615
|
+
showFlags: hasSopFlag,
|
|
616
|
+
|
|
617
|
+
runAIFlag: typeof doc.runAIFlag === 'number' ? doc.runAIFlag : 0,
|
|
618
|
+
|
|
619
|
+
showRunAIFlag: ( typeof doc.runAIQuestionCount === 'number' ? doc.runAIQuestionCount : 0 ) > 0,
|
|
510
620
|
|
|
511
621
|
submittedBy: doc.userName || '--',
|
|
512
622
|
|
|
513
623
|
country: doc.country || '--',
|
|
514
624
|
|
|
625
|
+
userImage,
|
|
626
|
+
|
|
627
|
+
userSignature,
|
|
628
|
+
|
|
629
|
+
showUserVerification: Boolean( userImage || userSignature ),
|
|
630
|
+
|
|
515
631
|
hasCompliancePage,
|
|
516
632
|
|
|
517
633
|
detailPageStart,
|
|
@@ -567,7 +683,7 @@ function buildFromViewChecklistApi( getchecklistData, viewchecklistData, brandIn
|
|
|
567
683
|
|
|
568
684
|
const {
|
|
569
685
|
|
|
570
|
-
totalScore, maxScore, sectionInsights, questionAnswers, flags, numQuestions,
|
|
686
|
+
totalScore, maxScore, sectionInsights, questionAnswers, flags, numQuestions, hasSopFlag,
|
|
571
687
|
|
|
572
688
|
} = mapSectionsFromQuestionAnswer( questionAnswer );
|
|
573
689
|
|
|
@@ -622,6 +738,9 @@ function buildFromViewChecklistApi( getchecklistData, viewchecklistData, brandIn
|
|
|
622
738
|
} );
|
|
623
739
|
}
|
|
624
740
|
|
|
741
|
+
const userImage = checklistAnswer?.userImage || checklistInfo?.userImage || '';
|
|
742
|
+
const userSignature = checklistAnswer?.userSignature || checklistInfo?.userSignature || '';
|
|
743
|
+
|
|
625
744
|
return {
|
|
626
745
|
|
|
627
746
|
brandLogo: brandInfo.brandLogo || '',
|
|
@@ -650,12 +769,22 @@ function buildFromViewChecklistApi( getchecklistData, viewchecklistData, brandIn
|
|
|
650
769
|
|
|
651
770
|
numFlags: checklistAnswer?.flagCount ?? flags.length,
|
|
652
771
|
|
|
653
|
-
|
|
772
|
+
showFlags: hasSopFlag,
|
|
773
|
+
|
|
774
|
+
runAIFlag: checklistAnswer?.runAIFlag ?? checklistInfo?.runAIFlag ?? checklistAnswer?.aiBreachedCount ?? 0,
|
|
775
|
+
|
|
776
|
+
showRunAIFlag: ( checklistInfo?.runAIQuestionCount ?? checklistAnswer?.runAIQuestionCount ?? 0 ) > 0,
|
|
654
777
|
|
|
655
778
|
submittedBy: checklistInfo?.submittedBy || storeProfile?.userName || '--',
|
|
656
779
|
|
|
657
780
|
country: storeProfile?.Country || '--',
|
|
658
781
|
|
|
782
|
+
userImage,
|
|
783
|
+
|
|
784
|
+
userSignature,
|
|
785
|
+
|
|
786
|
+
showUserVerification: Boolean( userImage || userSignature ),
|
|
787
|
+
|
|
659
788
|
hasCompliancePage,
|
|
660
789
|
|
|
661
790
|
detailPageStart,
|
|
@@ -782,6 +911,11 @@ export function createImageCache() {
|
|
|
782
911
|
}
|
|
783
912
|
|
|
784
913
|
|
|
914
|
+
if ( resolvedData.userImage && resolvedData.userImage.startsWith( 'http' ) ) {
|
|
915
|
+
urls.add( resolvedData.userImage );
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
|
|
785
919
|
const collectFromSection = ( section ) => {
|
|
786
920
|
section.questions?.forEach( ( q ) => {
|
|
787
921
|
if ( q.questionReferenceImage && q.questionReferenceImage.startsWith( 'http' ) ) urls.add( q.questionReferenceImage );
|
|
@@ -806,6 +940,10 @@ export function createImageCache() {
|
|
|
806
940
|
} );
|
|
807
941
|
}
|
|
808
942
|
} );
|
|
943
|
+
|
|
944
|
+
q.mediaItems?.forEach( ( m ) => {
|
|
945
|
+
if ( typeof m.url === 'string' && m.url.startsWith( 'http' ) ) urls.add( m.url );
|
|
946
|
+
} );
|
|
809
947
|
} );
|
|
810
948
|
};
|
|
811
949
|
|
|
@@ -842,6 +980,11 @@ export function createImageCache() {
|
|
|
842
980
|
}
|
|
843
981
|
|
|
844
982
|
|
|
983
|
+
if ( resolvedData.userImage ) {
|
|
984
|
+
resolvedData.userImage = cache.get( resolvedData.userImage ) || resolvedData.userImage;
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
|
|
845
988
|
const replaceInSection = ( section ) => {
|
|
846
989
|
section.questions?.forEach( ( q ) => {
|
|
847
990
|
if ( q.questionReferenceImage && cache.has( q.questionReferenceImage ) ) q.questionReferenceImage = cache.get( q.questionReferenceImage );
|
|
@@ -864,6 +1007,12 @@ export function createImageCache() {
|
|
|
864
1007
|
ua.validationImage = ua.validationImage.map( ( u ) => ( cache.has( u ) ? cache.get( u ) : u ) );
|
|
865
1008
|
}
|
|
866
1009
|
} );
|
|
1010
|
+
|
|
1011
|
+
if ( q.mediaItems?.length ) {
|
|
1012
|
+
q.mediaItems.forEach( ( m ) => {
|
|
1013
|
+
if ( cache.has( m.url ) ) m.url = cache.get( m.url );
|
|
1014
|
+
} );
|
|
1015
|
+
}
|
|
867
1016
|
} );
|
|
868
1017
|
};
|
|
869
1018
|
|
|
@@ -936,11 +1085,21 @@ export function resolveTemplateUrls( templateData, baseUrl = 'https://d1r0hc2ssk
|
|
|
936
1085
|
ua.validationImage = ua.validationImage.map( ( ele ) => resolveUrl( ele ) );
|
|
937
1086
|
}
|
|
938
1087
|
|
|
1088
|
+
if ( ua?.validationVideo?.length ) {
|
|
1089
|
+
ua.validationVideo = ua.validationVideo.map( ( ele ) => resolveUrl( ele ) );
|
|
1090
|
+
}
|
|
1091
|
+
|
|
939
1092
|
|
|
940
1093
|
if ( ua.answer && ua.answerType !== 'text' ) {
|
|
941
1094
|
ua.answer = resolveUrl( ua.answer );
|
|
942
1095
|
}
|
|
943
1096
|
} );
|
|
1097
|
+
|
|
1098
|
+
if ( q.mediaItems?.length ) {
|
|
1099
|
+
q.mediaItems.forEach( ( m ) => {
|
|
1100
|
+
m.url = resolveUrl( m.url );
|
|
1101
|
+
} );
|
|
1102
|
+
}
|
|
944
1103
|
} );
|
|
945
1104
|
};
|
|
946
1105
|
|
|
@@ -954,11 +1113,14 @@ export function resolveTemplateUrls( templateData, baseUrl = 'https://d1r0hc2ssk
|
|
|
954
1113
|
|
|
955
1114
|
resolvedData.sections?.forEach( resolveQuestionMedia );
|
|
956
1115
|
|
|
957
|
-
|
|
958
|
-
if ( resolvedData.brandLogo && !resolvedData.brandLogo.startsWith( 'http' ) ) {
|
|
1116
|
+
if ( resolvedData?.brandLogo && !resolvedData?.brandLogo?.startsWith( 'http' ) ) {
|
|
959
1117
|
resolvedData.brandLogo = resolveUrl( resolvedData.brandLogo );
|
|
960
1118
|
}
|
|
961
1119
|
|
|
1120
|
+
if ( resolvedData?.userImage && !resolvedData.userImage.startsWith( 'http' ) && !resolvedData.userImage.startsWith( 'data:' ) ) {
|
|
1121
|
+
resolvedData.userImage = resolveUrl( resolvedData.userImage );
|
|
1122
|
+
}
|
|
1123
|
+
|
|
962
1124
|
|
|
963
1125
|
return resolvedData;
|
|
964
1126
|
}
|
|
@@ -1070,10 +1232,20 @@ export async function generateVisitChecklistPDF( templateData, baseUrl = 'https:
|
|
|
1070
1232
|
ua.validationImage = ua.validationImage.map( ( ele ) => resolveUrl( ele ) );
|
|
1071
1233
|
}
|
|
1072
1234
|
|
|
1235
|
+
if ( ua.validationVideo?.length ) {
|
|
1236
|
+
ua.validationVideo = ua.validationVideo.map( ( ele ) => resolveUrl( ele ) );
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1073
1239
|
if ( ua.answer && ua.answerType !== 'text' ) {
|
|
1074
1240
|
ua.answer = resolveUrl( ua.answer );
|
|
1075
1241
|
}
|
|
1076
1242
|
} );
|
|
1243
|
+
|
|
1244
|
+
if ( q.mediaItems?.length ) {
|
|
1245
|
+
q.mediaItems.forEach( ( m ) => {
|
|
1246
|
+
m.url = resolveUrl( m.url );
|
|
1247
|
+
} );
|
|
1248
|
+
}
|
|
1077
1249
|
} );
|
|
1078
1250
|
};
|
|
1079
1251
|
|
|
@@ -1087,6 +1259,10 @@ export async function generateVisitChecklistPDF( templateData, baseUrl = 'https:
|
|
|
1087
1259
|
resolvedData.brandLogo = resolveUrl( resolvedData.brandLogo );
|
|
1088
1260
|
}
|
|
1089
1261
|
|
|
1262
|
+
if ( resolvedData.userImage && !resolvedData.userImage.startsWith( 'http' ) && !resolvedData.userImage.startsWith( 'data:' ) ) {
|
|
1263
|
+
resolvedData.userImage = resolveUrl( resolvedData.userImage );
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1090
1266
|
|
|
1091
1267
|
const html = template( resolvedData );
|
|
1092
1268
|
|