tango-app-api-trax 3.8.25 → 3.8.26
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
|
@@ -4360,7 +4360,6 @@ export async function recurringFlagAlert( req, res ) {
|
|
|
4360
4360
|
],
|
|
4361
4361
|
},
|
|
4362
4362
|
}, { _id: 1, checkListName: 1, recurringFlag: 1, notifyFlags: 1, approver: 1, client_id: 1 } );
|
|
4363
|
-
console.log( JSON.stringify( checklistDetails ) );
|
|
4364
4363
|
if ( !checklistDetails.length ) {
|
|
4365
4364
|
return res.sendSuccess( 'No checklists configured for recurring flag' );
|
|
4366
4365
|
}
|
|
@@ -4470,9 +4469,11 @@ export async function recurringFlagAlert( req, res ) {
|
|
|
4470
4469
|
await Promise.all( [ ...byRecipient.entries() ].map( async ( [ recipient, items ] ) => {
|
|
4471
4470
|
const subjects = new Set( items.map( ( i ) => i.subjectId ) );
|
|
4472
4471
|
const checklists = new Set( items.map( ( i ) => i.checklistId ) );
|
|
4473
|
-
console.log( checklists );
|
|
4474
4472
|
const isMultiStore = subjects.size > 1; // "isMultiStore" name retained for template back-compat
|
|
4475
4473
|
const isMultiChecklist = !isMultiStore && checklists.size > 1;
|
|
4474
|
+
// Sub-mode of multi-store when the recipient's flagged subjects all share a single checklist.
|
|
4475
|
+
// Drives a tighter email layout (no Checklist column, no "Total Checklists" line, checklist name in intro).
|
|
4476
|
+
const isMultiStoreSingleChecklist = isMultiStore && checklists.size === 1;
|
|
4476
4477
|
// Threshold for the message line — when grouping spans multiple checklists/subjects, take min threshold seen.
|
|
4477
4478
|
const thresholdShown = items.reduce( ( acc, it ) => Math.min( acc, it.days ), items[0].days );
|
|
4478
4479
|
|
|
@@ -4521,9 +4522,10 @@ export async function recurringFlagAlert( req, res ) {
|
|
|
4521
4522
|
checklistName: g.checklistName,
|
|
4522
4523
|
lastSubmittedBy: g.lastSubmittedBy,
|
|
4523
4524
|
lastSubmissionDate: g.lastSubmissionDate,
|
|
4524
|
-
days: g.questionCount, //
|
|
4525
|
+
days: g.questionCount, // legacy alias kept for back-compat with older template builds
|
|
4525
4526
|
flagCount: g.questionCount,
|
|
4526
4527
|
runAICount: g.runAICount,
|
|
4528
|
+
totalFlags: g.questionCount + g.runAICount,
|
|
4527
4529
|
} ) );
|
|
4528
4530
|
|
|
4529
4531
|
// Excel attachment keeps per-question detail (one row per flagged question).
|
|
@@ -4546,6 +4548,7 @@ export async function recurringFlagAlert( req, res ) {
|
|
|
4546
4548
|
threshold: thresholdShown,
|
|
4547
4549
|
isMultiStore,
|
|
4548
4550
|
isMultiChecklist,
|
|
4551
|
+
isMultiStoreSingleChecklist,
|
|
4549
4552
|
showTable: isMultiStore || isMultiChecklist,
|
|
4550
4553
|
hasAttachment,
|
|
4551
4554
|
domain: flagDomain,
|
|
@@ -4563,11 +4566,15 @@ export async function recurringFlagAlert( req, res ) {
|
|
|
4563
4566
|
totalChecklists: checklists.size,
|
|
4564
4567
|
totalFlags: items.length,
|
|
4565
4568
|
};
|
|
4569
|
+
if ( isMultiStoreSingleChecklist ) {
|
|
4570
|
+
// Show the single checklist name in the intro line for this sub-mode.
|
|
4571
|
+
data.checklistName = items[0].checklistName;
|
|
4572
|
+
}
|
|
4566
4573
|
} else if ( isMultiChecklist ) {
|
|
4567
4574
|
data.subjectName = items[0].subjectName;
|
|
4568
4575
|
data.storeName = items[0].subjectName;
|
|
4569
4576
|
} else {
|
|
4570
|
-
// Single mode: one (subject, checklist) —
|
|
4577
|
+
// Single mode: one (subject, checklist) — totalFlags = sop question flags + runAI flags.
|
|
4571
4578
|
const single = rows[0];
|
|
4572
4579
|
data.subjectName = single.subjectName;
|
|
4573
4580
|
data.storeName = single.subjectName;
|
|
@@ -4575,9 +4582,8 @@ export async function recurringFlagAlert( req, res ) {
|
|
|
4575
4582
|
data.lastSubmittedBy = single.lastSubmittedBy;
|
|
4576
4583
|
data.lastSubmissionDate = single.lastSubmissionDate;
|
|
4577
4584
|
data.flagCount = single.flagCount;
|
|
4578
|
-
data.flagCountPlural = single.flagCount > 1;
|
|
4579
4585
|
data.runAICount = single.runAICount;
|
|
4580
|
-
data.
|
|
4586
|
+
data.totalFlags = single.totalFlags;
|
|
4581
4587
|
}
|
|
4582
4588
|
|
|
4583
4589
|
const html = compiled( { data } );
|
|
@@ -4602,7 +4608,6 @@ export async function recurringFlagAlert( req, res ) {
|
|
|
4602
4608
|
logger.error( { functionName: 'recurringFlagAlert.buildExcel', error: e } );
|
|
4603
4609
|
}
|
|
4604
4610
|
}
|
|
4605
|
-
console.log( params.toEmail );
|
|
4606
4611
|
sendEmailWithSES( params.toEmail, params.mailSubject, params.htmlBody, params.attachment, params.sourceEmail );
|
|
4607
4612
|
sentSummary.push( { recipient, count: items.length, mode: isMultiStore ? 'multi-store' : ( isMultiChecklist ? 'multi-checklist' : 'single' ) } );
|
|
4608
4613
|
} ) );
|
|
@@ -67,7 +67,9 @@
|
|
|
67
67
|
<div style="margin-top: 0px;margin-bottom: 0px;font-size: 16px;line-height: 28px;color: #82899a;">
|
|
68
68
|
<span style="font-weight: 400;color: #121A26;line-height: 140%;">
|
|
69
69
|
Hi,<br/>
|
|
70
|
-
{{#if data.
|
|
70
|
+
{{#if data.isMultiStoreSingleChecklist}}
|
|
71
|
+
Recurring flags has been detected across multiple {{data.subjectLabelPluralLower}} in recent <b>{{data.checklistName}}</b> on recent submissions, exceeding the configured threshold of {{data.threshold}} occurrences.
|
|
72
|
+
{{else if data.isMultiStore}}
|
|
71
73
|
Recurring flags has been detected across multiple {{data.subjectLabelPluralLower}} and across multiple checklists on recent submissions, exceeding the configured threshold of {{data.threshold}} occurrences.
|
|
72
74
|
{{else if data.isMultiChecklist}}
|
|
73
75
|
A Recurring flags has been identified for {{data.subjectLabelLower}} <b>{{data.subjectName}}</b> across multiple checklists on recent submissions, exceeding the configured threshold of {{data.threshold}} occurrences.
|
|
@@ -87,7 +89,9 @@
|
|
|
87
89
|
<b>Key Highlights:</b>
|
|
88
90
|
<ul style="margin:8px 0 0 0;padding-left:18px;">
|
|
89
91
|
<li>Total {{data.subjectLabelPlural}} with Recurring Flags: {{data.highlights.totalSubjects}}</li>
|
|
92
|
+
{{#unless data.isMultiStoreSingleChecklist}}
|
|
90
93
|
<li>Total Checklists with Recurring Flags: {{data.highlights.totalChecklists}}</li>
|
|
94
|
+
{{/unless}}
|
|
91
95
|
<li>Total Recurring Flags: {{data.highlights.totalFlags}}</li>
|
|
92
96
|
</ul>
|
|
93
97
|
</div>
|
|
@@ -141,12 +145,7 @@
|
|
|
141
145
|
<tr bgcolor="#ffffff">
|
|
142
146
|
<td class="flagText" style="padding-left:30px;line-height: 24px;">No of Flags :</td>
|
|
143
147
|
<td></td><td></td>
|
|
144
|
-
<td class="flagText">{{data.
|
|
145
|
-
</tr>
|
|
146
|
-
<tr bgcolor="#ffffff">
|
|
147
|
-
<td class="flagText" style="padding-left:30px;line-height: 24px;">Run AI Flags :</td>
|
|
148
|
-
<td></td><td></td>
|
|
149
|
-
<td class="flagText">{{data.runAICount}} Run AI Flag{{#if data.runAICountPlural}}s{{/if}}</td>
|
|
148
|
+
<td class="flagText">{{data.totalFlags}} (Question Flags: {{data.flagCount}}, Run AI Flags: {{data.runAICount}})</td>
|
|
150
149
|
</tr>
|
|
151
150
|
</table>
|
|
152
151
|
</td>
|
|
@@ -164,22 +163,20 @@
|
|
|
164
163
|
<thead>
|
|
165
164
|
<tr>
|
|
166
165
|
{{#if data.isMultiStore}}<th>{{data.subjectLabel}} Name</th>{{/if}}
|
|
167
|
-
<th>Checklist Name</th>
|
|
166
|
+
{{#unless data.isMultiStoreSingleChecklist}}<th>Checklist Name</th>{{/unless}}
|
|
168
167
|
<th>Last Submitted By</th>
|
|
169
168
|
<th>Last Submission Date</th>
|
|
170
169
|
<th>Total Recurring Flags</th>
|
|
171
|
-
<th>Run AI Flags</th>
|
|
172
170
|
</tr>
|
|
173
171
|
</thead>
|
|
174
172
|
<tbody>
|
|
175
173
|
{{#each data.rows}}
|
|
176
174
|
<tr>
|
|
177
175
|
{{#if ../data.isMultiStore}}<td>{{this.subjectName}}</td>{{/if}}
|
|
178
|
-
<td>{{this.checklistName}}</td>
|
|
176
|
+
{{#unless ../data.isMultiStoreSingleChecklist}}<td>{{this.checklistName}}</td>{{/unless}}
|
|
179
177
|
<td>{{this.lastSubmittedBy}}</td>
|
|
180
178
|
<td>{{this.lastSubmissionDate}}</td>
|
|
181
|
-
<td>{{this.
|
|
182
|
-
<td>{{this.runAICount}}</td>
|
|
179
|
+
<td>{{this.totalFlags}} (Question Flags: {{this.flagCount}}, Run AI Flags: {{this.runAICount}})</td>
|
|
183
180
|
</tr>
|
|
184
181
|
{{/each}}
|
|
185
182
|
</tbody>
|
|
@@ -70,6 +70,8 @@
|
|
|
70
70
|
.q-answer-text.flagged{color:#a32d2d}
|
|
71
71
|
.q-answer-media{margin-top:8px}
|
|
72
72
|
.q-answer-media img,.q-answer-media video,.q-answer-item td img{display:block;width:200px;height:180px;object-fit:cover;border-radius:6px;margin-bottom:6px}
|
|
73
|
+
.img-grid{display:flex;flex-wrap:wrap;gap:8px}
|
|
74
|
+
.img-grid img{margin-bottom:0}
|
|
73
75
|
.q-answer-link{font-size:12px;color:#0085D2;text-decoration:underline;word-break:break-all}
|
|
74
76
|
.q-answer-caption{font-size:11px;color:#666;margin-bottom:4px}
|
|
75
77
|
.q-answer-remarks{font-size:11px;color:#666;margin-top:6px;white-space:pre-line}
|
|
@@ -188,9 +190,11 @@
|
|
|
188
190
|
{{#if this.multiQuestionReferenceImage.length}}
|
|
189
191
|
<div class="q-answer-media">
|
|
190
192
|
<div class="q-answer-caption">Question Reference Images</div>
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
193
|
+
<div class="img-grid">
|
|
194
|
+
{{#each this.multiQuestionReferenceImage}}
|
|
195
|
+
<img src="{{this}}" alt="Reference Image" />
|
|
196
|
+
{{/each}}
|
|
197
|
+
</div>
|
|
194
198
|
</div>
|
|
195
199
|
{{/if}}
|
|
196
200
|
{{!-- <span class="q-ans {{#if this.isYes}}ans-yes{{else}}{{#if this.isNo}}ans-no{{/if}}{{/if}}">{{#if this.isYes}}✓ Yes{{else}}{{#if this.isNo}}✗ No{{else}}{{this.answerDisplay}}{{/if}}{{/if}}</span> --}}
|
|
@@ -198,25 +202,6 @@
|
|
|
198
202
|
<div class="q-answer-list">
|
|
199
203
|
{{#each this.userAnswer}}
|
|
200
204
|
<div class="q-answer-item">
|
|
201
|
-
{{#neq ../answerType 'image/video'}}
|
|
202
|
-
{{#neq ../answerType 'multipleImage'}}
|
|
203
|
-
{{#if this.multiReferenceImage.length}}
|
|
204
|
-
<div class="q-answer-media">
|
|
205
|
-
<div class="q-answer-caption">Reference Images</div>
|
|
206
|
-
{{#each this.multiReferenceImage}}
|
|
207
|
-
<img src="{{this}}" alt="Reference Image" />
|
|
208
|
-
{{/each}}
|
|
209
|
-
</div>
|
|
210
|
-
{{else}}
|
|
211
|
-
{{#if this.referenceImage}}
|
|
212
|
-
<div class="q-answer-media">
|
|
213
|
-
<div class="q-answer-caption">Reference Image</div>
|
|
214
|
-
<img src="{{this.referenceImage}}" alt="Reference Image" />
|
|
215
|
-
</div>
|
|
216
|
-
{{/if}}
|
|
217
|
-
{{/if}}
|
|
218
|
-
{{/neq}}
|
|
219
|
-
{{/neq}}
|
|
220
205
|
{{#eq this.answerType 'text'}}
|
|
221
206
|
{{#if this.answer}}
|
|
222
207
|
<div class="q-answer-text {{#if this.sopFlag}}flagged{{/if}}">{{this.answer}}</div>
|
|
@@ -231,8 +216,29 @@
|
|
|
231
216
|
{{/if}}
|
|
232
217
|
{{/eq}}
|
|
233
218
|
|
|
234
|
-
<table style="width:100%;margin-top:8px"><tr>
|
|
235
|
-
<td style="vertical-align:top">
|
|
219
|
+
<table style="width:100%;margin-top:8px;table-layout:fixed"><tr>
|
|
220
|
+
<td style="width:50%;vertical-align:top;padding-right:8px">
|
|
221
|
+
{{#neq ../answerType 'image/video'}}
|
|
222
|
+
{{#neq ../answerType 'multipleImage'}}
|
|
223
|
+
{{#if this.multiReferenceImage.length}}
|
|
224
|
+
<div class="q-answer-media">
|
|
225
|
+
<div class="q-answer-caption">Reference Images</div>
|
|
226
|
+
{{#each this.multiReferenceImage}}
|
|
227
|
+
<img src="{{this}}" alt="Reference Image" />
|
|
228
|
+
{{/each}}
|
|
229
|
+
</div>
|
|
230
|
+
{{else}}
|
|
231
|
+
{{#if this.referenceImage}}
|
|
232
|
+
<div class="q-answer-media">
|
|
233
|
+
<div class="q-answer-caption">Reference Image</div>
|
|
234
|
+
<img src="{{this.referenceImage}}" alt="Reference Image" />
|
|
235
|
+
</div>
|
|
236
|
+
{{/if}}
|
|
237
|
+
{{/if}}
|
|
238
|
+
{{/neq}}
|
|
239
|
+
{{/neq}}
|
|
240
|
+
</td>
|
|
241
|
+
<td style="width:50%;vertical-align:top;padding-left:8px">
|
|
236
242
|
{{#eq this.answerType 'image'}}
|
|
237
243
|
{{#if this.answer}}
|
|
238
244
|
<div class="q-answer-caption">Uploaded Image</div>
|
|
@@ -169,13 +169,15 @@ function buildQuestionAnswerEntries( question ) {
|
|
|
169
169
|
|
|
170
170
|
const rawMultiRefSources = [
|
|
171
171
|
userAnswer?.multiReferenceImage,
|
|
172
|
-
matchedAnswer?.multiReferenceImage,
|
|
173
|
-
question?.answers?.[0]?.multiReferenceImage,
|
|
172
|
+
// matchedAnswer?.multiReferenceImage,
|
|
173
|
+
// question?.answers?.[0]?.multiReferenceImage,
|
|
174
174
|
];
|
|
175
175
|
let multiReferenceImage = [];
|
|
176
176
|
for ( const src of rawMultiRefSources ) {
|
|
177
177
|
const flat = flattenImageRefs( src );
|
|
178
|
-
if ( flat.length ) {
|
|
178
|
+
if ( flat.length ) {
|
|
179
|
+
multiReferenceImage = flat; break;
|
|
180
|
+
}
|
|
179
181
|
}
|
|
180
182
|
const validationImage = flattenImageRefs( userAnswer?.validationImage );
|
|
181
183
|
|
|
@@ -920,7 +922,6 @@ export function resolveTemplateUrls( templateData, baseUrl = 'https://d1r0hc2ssk
|
|
|
920
922
|
q.multiQuestionReferenceImage = q.multiQuestionReferenceImage.map( ( ele ) => resolveUrl( ele ) );
|
|
921
923
|
}
|
|
922
924
|
q.userAnswer?.forEach( ( ua ) => {
|
|
923
|
-
|
|
924
925
|
if ( ua.multiReferenceImage?.length ) {
|
|
925
926
|
ua.multiReferenceImage = ua.multiReferenceImage.map( ( ele ) => resolveUrl( ele ) );
|
|
926
927
|
}
|