@sunbird-cb/toc 0.0.21 โ†’ 0.0.22

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.
@@ -2045,17 +2045,6 @@ class AppTocService {
2045
2045
  child.mimeType === 'application/vnd.sunbird.questionset';
2046
2046
  if (isAssessment) {
2047
2047
  }
2048
- // Debug: Log when adding item with isPreAssessment flag to hashmap
2049
- if (child.isPreAssessment === true) {
2050
- console.log('๐Ÿ” [HASHMAP BUILD] Adding pre-assessment to hashmap:', {
2051
- id: child.identifier,
2052
- name: child.name,
2053
- isPreAssessment: localMap.isPreAssessment,
2054
- parent: localMap.parent,
2055
- completionStatus: localMap.completionStatus,
2056
- status: localMap.status
2057
- });
2058
- }
2059
2048
  this.hashmap[child.identifier] = localMap;
2060
2049
  });
2061
2050
  }
@@ -2100,7 +2089,6 @@ class AppTocService {
2100
2089
  // 4. Different regular Course
2101
2090
  const isNewContent = this.currentRootContentId !== hierarchyData.identifier;
2102
2091
  if (isNewContent) {
2103
- console.log(`๐Ÿงน [HASHMAP] Clearing hashmap - navigating from ${this.currentRootContentId} to ${hierarchyData.identifier}`);
2104
2092
  this.hashmap = {};
2105
2093
  this.currentRootContentId = hierarchyData.identifier;
2106
2094
  }
@@ -2142,63 +2130,8 @@ class AppTocService {
2142
2130
  this.hashmap = { ...this.hashmap };
2143
2131
  }
2144
2132
  }
2145
- /**
2146
- * Pre-compute milestone locking status for all milestones in Learning Pathway
2147
- * This avoids expensive calculations in component getters
2148
- *
2149
- * Locking Rules:
2150
- * 0. If user is not enrolled, ALL milestones are locked
2151
- * 1. All milestones are locked by default
2152
- * 2. Milestone 1 (M1) unlocks when pre-assessment is completed
2153
- * 3. Milestone N (N > 1) unlocks when:
2154
- * - All mandatory learning items in Milestone N-1 are completed
2155
- * - The assessment of Milestone N-1 is completed
2156
- */
2157
- /**
2158
- * โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
2159
- * LEARNING PATHWAY MILESTONE LOCKING SYSTEM - SINGLE SOURCE OF TRUTH
2160
- * โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
2161
- *
2162
- * This method is the SINGLE SOURCE OF TRUTH for all milestone and assessment locking.
2163
- * All locking logic is computed here and stored in the hashmap.
2164
- * Components READ ONLY from the hashmap - they do NOT compute locks themselves.
2165
- *
2166
- * LOCKING RULES:
2167
- * โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
2168
- * 1. DEFAULT STATE: All milestones are LOCKED by default
2169
- *
2170
- * 2. MILESTONE 1 UNLOCKING:
2171
- * - Unlocks when: Pre-assessment is 100% complete
2172
- * - Lock message: "Complete the preliminary assessment to unlock this milestone"
2173
- *
2174
- * 3. MILESTONE N (N >= 2) UNLOCKING:
2175
- * - Unlocks when: Previous milestone is 100% complete
2176
- * - Previous milestone is complete when:
2177
- * a) All MANDATORY courses are 100% complete
2178
- * b) Milestone assessment is 100% complete
2179
- * - Lock message: "Complete all mandatory content and assessment in Milestone N-1"
2180
- *
2181
- * 4. ASSESSMENT LOCKING (within unlocked milestones):
2182
- * - Assessment locked until: All MANDATORY courses in SAME milestone complete
2183
- * - Optional courses do NOT affect assessment locking
2184
- * - Assessment lock message: "Complete all mandatory items to unlock the assessment"
2185
- * - Once assessment is completed, it stays unlocked
2186
- *
2187
- * 5. PARENT MILESTONE LOCKING:
2188
- * - All content inside locked milestone gets isParentMilestoneLocked = true
2189
- * - This includes courses, assessments, nested resources
2190
- *
2191
- * 6. MANDATORY vs OPTIONAL:
2192
- * - By default, ALL courses are mandatory (unless isMandatory: false)
2193
- * - Optional courses do NOT block progression
2194
- *
2195
- * โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
2196
- */
2197
2133
  computeMilestoneLockingStatus(isEnrolled = true) {
2198
- console.log('๐Ÿš€ [MILESTONE LOCK] computeMilestoneLockingStatus CALLED with isEnrolled:', isEnrolled);
2199
- console.log('๐Ÿš€ [MILESTONE LOCK] Hashmap size:', Object.keys(this.hashmap).length);
2200
2134
  if (!this.hashmap || Object.keys(this.hashmap).length === 0) {
2201
- console.warn('โš ๏ธ Hashmap is empty - cannot compute milestone locking');
2202
2135
  return;
2203
2136
  }
2204
2137
  // STEP 1: Find all milestones and sort by index
@@ -2220,12 +2153,8 @@ class AppTocService {
2220
2153
  if (milestoneEntries.length === 0) {
2221
2154
  return;
2222
2155
  }
2223
- milestoneEntries.forEach((id, i) => {
2224
- console.log(` M${i + 1}: ${this.hashmap[id].name || id}`);
2225
- });
2226
2156
  // STEP 2: If user NOT enrolled, lock ALL milestones and children
2227
2157
  if (!isEnrolled) {
2228
- console.log('\nโš ๏ธ User NOT enrolled - locking ALL milestones and children');
2229
2158
  milestoneEntries.forEach(milestoneId => {
2230
2159
  this.hashmap[milestoneId].computedIsLocked = true;
2231
2160
  this.hashmap[milestoneId].unlockMessage = 'Enroll in this course to access milestones';
@@ -2242,7 +2171,6 @@ class AppTocService {
2242
2171
  }
2243
2172
  // STEP 3: Check pre-assessment completion
2244
2173
  const isPreAssessmentCompleted = this.checkPreAssessmentCompletion();
2245
- console.log('๐Ÿ” [MILESTONE LOCK] Pre-assessment completed:', isPreAssessmentCompleted ? 'โœ… YES' : 'โŒ NO');
2246
2174
  // STEP 4: Compute locking for each milestone
2247
2175
  milestoneEntries.forEach((milestoneId, index) => {
2248
2176
  const milestone = this.hashmap[milestoneId];
@@ -2255,17 +2183,11 @@ class AppTocService {
2255
2183
  this.hashmap[milestoneId].computedIsLocked = isLocked;
2256
2184
  this.hashmap[milestoneId].unlockMessage = isLocked ?
2257
2185
  'Complete the preliminary assessment to unlock this milestone' : '';
2258
- console.log(`๐Ÿ“Œ [MILESTONE 1] ${milestone.name}:`, {
2259
- isPreAssessmentCompleted,
2260
- isLocked: isLocked ? '๐Ÿ”’ LOCKED' : '๐Ÿ”“ UNLOCKED',
2261
- unlockMessage: this.hashmap[milestoneId].unlockMessage
2262
- });
2263
2186
  // For unlocked M1, check assessment locking
2264
2187
  if (!isLocked) {
2265
2188
  this.computeAssessmentLockingInMilestone(milestoneId);
2266
2189
  }
2267
2190
  else {
2268
- console.log(` โจฏ Milestone locked - marking all children as parent-locked`);
2269
2191
  this.markMilestoneChildrenAsParentLocked(milestoneId, true);
2270
2192
  }
2271
2193
  return;
@@ -2280,63 +2202,39 @@ class AppTocService {
2280
2202
  const prevStatus = Number(previousMilestone.status) || 0;
2281
2203
  const prevCompletedLeafNodes = Number(previousMilestone.completedLeafNodesCount) || 0;
2282
2204
  const prevLeafNodesCount = Number(previousMilestone.leafNodesCount) || 0;
2283
- console.log(`๐Ÿ” [MILESTONE ${milestoneNum}] Checking if previous M${index} is complete:`, {
2284
- previousMilestoneName: previousMilestone.name,
2285
- completionPercentage: prevCompletionPct,
2286
- completionStatus: prevCompletionStatus,
2287
- status: prevStatus,
2288
- completedLeafNodes: prevCompletedLeafNodes,
2289
- leafNodesCount: prevLeafNodesCount
2290
- });
2291
2205
  let previousMilestoneComplete = prevCompletionPct >= 100 ||
2292
2206
  prevCompletionStatus === 2 ||
2293
2207
  prevStatus === 2 ||
2294
2208
  (prevLeafNodesCount > 0 && prevCompletedLeafNodes >= prevLeafNodesCount);
2295
- console.log(` Primary check result: ${previousMilestoneComplete ? 'โœ… COMPLETE' : 'โŒ INCOMPLETE'}`);
2296
2209
  // Fallback: Check individual items
2297
2210
  if (!previousMilestoneComplete) {
2298
- console.log(` Running fallback check (mandatory content + assessment)...`);
2299
2211
  const isPreviousMilestoneAssessmentComplete = this.checkMilestoneAssessmentComplete(previousMilestoneId);
2300
2212
  const isPreviousMilestoneMandatoryComplete = this.checkMilestoneMandatoryContentComplete(previousMilestoneId);
2301
2213
  previousMilestoneComplete = isPreviousMilestoneAssessmentComplete && isPreviousMilestoneMandatoryComplete;
2302
- console.log(` Fallback check: mandatory=${isPreviousMilestoneMandatoryComplete}, assessment=${isPreviousMilestoneAssessmentComplete}, result=${previousMilestoneComplete}`);
2303
2214
  }
2304
2215
  const isLocked = !previousMilestoneComplete;
2305
2216
  this.hashmap[milestoneId].computedIsLocked = isLocked;
2306
2217
  this.hashmap[milestoneId].unlockMessage = isLocked ?
2307
2218
  `Complete all mandatory content and assessment in Milestone ${index} to unlock this milestone` : '';
2308
- console.log(` ๐Ÿ“Š [MILESTONE ${milestoneNum}] ${milestone.name}:`, {
2309
- previousMilestoneComplete: previousMilestoneComplete ? 'โœ… YES' : 'โŒ NO',
2310
- isLocked: isLocked ? '๐Ÿ”’ LOCKED' : '๐Ÿ”“ UNLOCKED',
2311
- unlockMessage: this.hashmap[milestoneId].unlockMessage
2312
- });
2313
2219
  // For unlocked milestones, check assessment locking
2314
2220
  if (!isLocked) {
2315
2221
  this.computeAssessmentLockingInMilestone(milestoneId);
2316
2222
  }
2317
2223
  else {
2318
- console.log(` โจฏ Milestone locked - marking all children as parent-locked`);
2319
2224
  this.markMilestoneChildrenAsParentLocked(milestoneId, true);
2320
2225
  }
2321
2226
  }
2322
2227
  else {
2323
2228
  this.hashmap[milestoneId].computedIsLocked = true;
2324
2229
  this.hashmap[milestoneId].unlockMessage = 'Previous milestone not found';
2325
- console.log(` ๐Ÿ”’ LOCKED (previous milestone not found)`);
2326
2230
  }
2327
2231
  });
2328
2232
  // STEP 4.5: Debug log milestone leaf nodes and their completion status
2329
- console.log('\n๐Ÿ“Š Milestone Leaf Nodes Completion Status:');
2330
2233
  milestoneEntries.forEach((milestoneId, index) => {
2331
2234
  const milestone = this.hashmap[milestoneId];
2332
2235
  if (!milestone)
2333
2236
  return;
2334
- console.log(` Leaf Nodes Array:`, milestone.leafNodes);
2335
- console.log(` Leaf Nodes Count: ${milestone.leafNodesCount}`);
2336
- console.log(` Completed Leaf Nodes Count: ${milestone.completedLeafNodesCount || 0}`);
2337
- console.log(` Completion %: ${milestone.completionPercentage}%`);
2338
2237
  if (milestone.leafNodes && milestone.leafNodes.length > 0) {
2339
- console.log(` Individual Leaf Node Status:`);
2340
2238
  milestone.leafNodes.forEach((leafId, i) => {
2341
2239
  const leafData = this.hashmap[leafId];
2342
2240
  if (leafData) {
@@ -2344,26 +2242,11 @@ class AppTocService {
2344
2242
  leafData.status === 2 ||
2345
2243
  (leafData.completionPercentage && leafData.completionPercentage >= 100) ||
2346
2244
  (leafData.progress && leafData.progress >= 100);
2347
- console.log(` ${i + 1}. ${leafData.name || leafId} [${leafData.primaryCategory}]:`, {
2348
- id: leafId,
2349
- completionStatus: leafData.completionStatus,
2350
- status: leafData.status,
2351
- completionPercentage: leafData.completionPercentage,
2352
- progress: leafData.progress,
2353
- isComplete: isComplete ? 'โœ…' : 'โŒ'
2354
- });
2355
- }
2356
- else {
2357
- console.log(` ${i + 1}. โš ๏ธ Leaf node ${leafId} NOT FOUND in hashmap`);
2358
2245
  }
2359
2246
  });
2360
2247
  }
2361
- else {
2362
- console.log(` โš ๏ธ No leaf nodes defined for this milestone`);
2363
- }
2364
2248
  });
2365
2249
  // STEP 5: Compute parent milestone lock status for ALL children
2366
- console.log('\n๐Ÿ”— Computing parent milestone locks for all children...');
2367
2250
  Object.keys(this.hashmap).forEach(key => {
2368
2251
  const item = this.hashmap[key];
2369
2252
  if (item.isMilestone)
@@ -2392,19 +2275,11 @@ class AppTocService {
2392
2275
  this.hashmap[key].isParentMilestoneLocked = false;
2393
2276
  }
2394
2277
  });
2395
- // STEP 6: Trigger hashmap update
2396
- console.log('โœ… Milestone locking computation COMPLETE');
2397
2278
  // Debug: Log final lock status for all milestones
2398
2279
  const milestonesFinal = Object.keys(this.hashmap).filter(key => this.hashmap[key].isMilestone ||
2399
2280
  this.hashmap[key].primaryCategory === 'Milestone' ||
2400
2281
  this.hashmap[key].courseCategory === 'Milestone');
2401
- console.log('๐Ÿ“Š [FINAL LOCK STATUS] All milestones:');
2402
- milestonesFinal.forEach((id, i) => {
2403
- const m = this.hashmap[id];
2404
- console.log(` ${i + 1}. ${m.name}: computedIsLocked=${m.computedIsLocked}, unlockMessage="${m.unlockMessage || 'N/A'}"`);
2405
- });
2406
2282
  this.hashmap = { ...this.hashmap };
2407
- console.log('๐Ÿ“ก [SERVICE] Broadcasting hashmap update with computedIsLocked values');
2408
2283
  this.hashmapUpdated.next({ timestamp: Date.now(), hashmap: this.hashmap });
2409
2284
  }
2410
2285
  /**
@@ -2412,27 +2287,21 @@ class AppTocService {
2412
2287
  * Called from viewer-util.service.ts after progress updates
2413
2288
  */
2414
2289
  triggerMilestoneLockUpdate() {
2415
- console.log('๐Ÿ”” [TRIGGER] triggerMilestoneLockUpdate called');
2416
2290
  // Check if we have a Learning Pathway in the hashmap
2417
2291
  const hasLearningPathway = Object.keys(this.hashmap).some(key => {
2418
2292
  const item = this.hashmap[key];
2419
2293
  // Check using OR condition - either flag indicates Learning Pathway
2420
2294
  return item.isLearningPathway === true || item.courseCategory === 'Learning Pathway';
2421
2295
  });
2422
- console.log(` Is Learning Pathway: ${hasLearningPathway}`);
2423
2296
  if (hasLearningPathway) {
2424
- console.log('๐Ÿ”„ [TRIGGER] Triggering milestone lock recomputation after progress update');
2425
2297
  // Assume enrolled since progress was just updated
2426
2298
  this.computeMilestoneLockingStatus(true);
2427
2299
  }
2428
2300
  else {
2429
- console.log('๐Ÿ”„ [TRIGGER] Regular content - emitting hashmap update for top-bar refresh');
2430
2301
  // For regular content (non-Learning Pathway), just emit the hashmap update
2431
2302
  // so the top-bar component can recalculate the completion count
2432
2303
  this.hashmap = { ...this.hashmap };
2433
- console.log('๐Ÿ“ก [TRIGGER] Broadcasting hashmap update event');
2434
2304
  this.hashmapUpdated.next({ timestamp: Date.now(), hashmap: this.hashmap });
2435
- console.log('โœ… [TRIGGER] Hashmap update broadcasted');
2436
2305
  }
2437
2306
  }
2438
2307
  /**
@@ -2440,8 +2309,6 @@ class AppTocService {
2440
2309
  * Pre-assessment is typically a Course Assessment at the root level of Learning Pathway (before milestones)
2441
2310
  */
2442
2311
  checkPreAssessmentCompletion() {
2443
- console.log('๐Ÿ” [PRE-ASSESSMENT] Starting pre-assessment completion check');
2444
- console.log('๐Ÿ” [PRE-ASSESSMENT] Hashmap keys:', Object.keys(this.hashmap).length);
2445
2312
  // Find the Learning Pathway root - check multiple conditions
2446
2313
  let learningPathwayId = null;
2447
2314
  for (const key of Object.keys(this.hashmap)) {
@@ -2451,36 +2318,17 @@ class AppTocService {
2451
2318
  item.isLearningPathway === true ||
2452
2319
  (item.primaryCategory === 'Blended Program' && item.courseCategory === 'Learning Pathway')) {
2453
2320
  learningPathwayId = key;
2454
- console.log('๐Ÿ” [PRE-ASSESSMENT] Found Learning Pathway root:', key, item.name);
2455
2321
  break;
2456
2322
  }
2457
2323
  }
2458
2324
  if (!learningPathwayId) {
2459
- console.log('โš ๏ธ [PRE-ASSESSMENT] Learning Pathway root NOT FOUND - returning false to keep milestones locked');
2460
2325
  return false;
2461
2326
  }
2462
- // Step 1: Look for items explicitly marked as pre-assessment (isPreAssessment flag)
2463
- console.log('๐Ÿ” [PRE-ASSESSMENT] Step 1: Looking for items with isPreAssessment=true flag...');
2464
- console.log('๐Ÿ” [PRE-ASSESSMENT] Dumping all hashmap items for debugging:');
2465
- for (const key of Object.keys(this.hashmap)) {
2466
- const item = this.hashmap[key];
2467
- if (item.isPreAssessment || item.primaryCategory === 'Course Assessment' || item.primaryCategory === 'Standalone Assessment') {
2468
- console.log(` ๐Ÿ“„ ${key}: isPreAssessment=${item.isPreAssessment}, primaryCategory=${item.primaryCategory}, parent=${item.parent}, completionStatus=${item.completionStatus}, status=${item.status}, completionPercentage=${item.completionPercentage}`);
2469
- }
2470
- }
2471
2327
  let foundPreAssessmentFlag = false;
2472
2328
  for (const key of Object.keys(this.hashmap)) {
2473
2329
  const item = this.hashmap[key];
2474
2330
  if (item.isPreAssessment === true) {
2475
2331
  foundPreAssessmentFlag = true;
2476
- console.log('๐Ÿ” [PRE-ASSESSMENT] Found item with isPreAssessment=true:', {
2477
- id: key,
2478
- name: item.name,
2479
- completionStatus: item.completionStatus,
2480
- status: item.status,
2481
- completionPercentage: item.completionPercentage,
2482
- progress: item.progress
2483
- });
2484
2332
  // STRICT CHECK: Only return true if completionStatus is EXACTLY 2 (not undefined, null, or 0)
2485
2333
  // completionPercentage check must be >= 100 AND be a number
2486
2334
  const completionStatus = Number(item.completionStatus);
@@ -2490,20 +2338,10 @@ class AppTocService {
2490
2338
  const isCompleted = (completionStatus === 2 || status === 2 ||
2491
2339
  (completionPercentage >= 100 && !isNaN(completionPercentage)) ||
2492
2340
  (progress >= 100 && !isNaN(progress)));
2493
- console.log('๐Ÿ” [PRE-ASSESSMENT] Pre-assessment completion result:', isCompleted ? 'โœ… COMPLETED' : 'โŒ NOT COMPLETED', {
2494
- completionStatusCheck: completionStatus === 2,
2495
- statusCheck: status === 2,
2496
- completionPercentageCheck: completionPercentage >= 100,
2497
- progressCheck: progress >= 100
2498
- });
2499
2341
  return isCompleted;
2500
2342
  }
2501
2343
  }
2502
- if (!foundPreAssessmentFlag) {
2503
- console.log('โš ๏ธ [PRE-ASSESSMENT] No item with isPreAssessment=true found in hashmap');
2504
- }
2505
2344
  // Step 2: Fallback - Look for Course Assessment that is a direct child of Learning Pathway (not a milestone child)
2506
- console.log('๐Ÿ” [PRE-ASSESSMENT] Step 2: Looking for Course Assessment direct child of Learning Pathway...');
2507
2345
  for (const key of Object.keys(this.hashmap)) {
2508
2346
  const item = this.hashmap[key];
2509
2347
  // Must be a direct child of the Learning Pathway
@@ -2515,14 +2353,6 @@ class AppTocService {
2515
2353
  // Must be a Course Assessment or Standalone Assessment
2516
2354
  if (item.primaryCategory !== 'Course Assessment' && item.primaryCategory !== 'Standalone Assessment')
2517
2355
  continue;
2518
- console.log('๐Ÿ” [PRE-ASSESSMENT] Found Course Assessment child of Learning Pathway:', {
2519
- id: key,
2520
- name: item.name,
2521
- primaryCategory: item.primaryCategory,
2522
- completionStatus: item.completionStatus,
2523
- status: item.status,
2524
- completionPercentage: item.completionPercentage
2525
- });
2526
2356
  // STRICT CHECK: Only return true if completionStatus is EXACTLY 2
2527
2357
  const completionStatus = Number(item.completionStatus);
2528
2358
  const status = Number(item.status);
@@ -2531,16 +2361,9 @@ class AppTocService {
2531
2361
  const isCompleted = (completionStatus === 2 || status === 2 ||
2532
2362
  (completionPercentage >= 100 && !isNaN(completionPercentage)) ||
2533
2363
  (progress >= 100 && !isNaN(progress)));
2534
- console.log('๐Ÿ” [PRE-ASSESSMENT] Course Assessment completion result:', isCompleted ? 'โœ… COMPLETED' : 'โŒ NOT COMPLETED', {
2535
- completionStatusCheck: completionStatus === 2,
2536
- statusCheck: status === 2,
2537
- completionPercentageCheck: completionPercentage >= 100,
2538
- progressCheck: progress >= 100
2539
- });
2540
2364
  return isCompleted;
2541
2365
  }
2542
2366
  // Step 3: If no pre-assessment found at all, keep milestones LOCKED (fail-safe)
2543
- console.log('โš ๏ธ [PRE-ASSESSMENT] No pre-assessment found in hashmap - returning FALSE to keep milestones LOCKED');
2544
2367
  return false;
2545
2368
  }
2546
2369
  /**
@@ -2552,7 +2375,6 @@ class AppTocService {
2552
2375
  const milestone = this.hashmap[milestoneId];
2553
2376
  let foundMilestoneAssessment = false;
2554
2377
  let isMilestoneAssessmentComplete = false;
2555
- console.log(`๐Ÿ” Checking milestone assessment for: ${milestoneId}`);
2556
2378
  // Check all items in hashmap that are DIRECT children of this milestone
2557
2379
  for (const key of Object.keys(this.hashmap)) {
2558
2380
  const item = this.hashmap[key];
@@ -2568,14 +2390,6 @@ class AppTocService {
2568
2390
  // Found the milestone assessment
2569
2391
  foundMilestoneAssessment = true;
2570
2392
  const isCompleted = item.completionStatus === 2 || item.status === 2 || item.completionPercentage >= 100 || item.progress >= 100;
2571
- console.log(`๐Ÿ“‹ Found milestone assessment (direct child): ${item.name || key}`, {
2572
- milestoneId,
2573
- assessmentId: key,
2574
- completionStatus: item.completionStatus,
2575
- status: item.status,
2576
- completionPercentage: item.completionPercentage,
2577
- isCompleted
2578
- });
2579
2393
  if (isCompleted) {
2580
2394
  isMilestoneAssessmentComplete = true;
2581
2395
  }
@@ -2585,10 +2399,8 @@ class AppTocService {
2585
2399
  // - If NO milestone assessment found โ†’ consider complete (no assessment requirement)
2586
2400
  // - If milestone assessment found โ†’ it must be completed
2587
2401
  if (!foundMilestoneAssessment) {
2588
- console.log(`โ„น๏ธ No milestone assessment (direct child) found for ${milestoneId} - considering as complete`);
2589
2402
  return true;
2590
2403
  }
2591
- console.log(`${isMilestoneAssessmentComplete ? 'โœ…' : 'โŒ'} Milestone ${milestoneId} assessment: ${isMilestoneAssessmentComplete ? 'COMPLETE' : 'INCOMPLETE'}`);
2592
2404
  return isMilestoneAssessmentComplete;
2593
2405
  }
2594
2406
  /**
@@ -2599,7 +2411,6 @@ class AppTocService {
2599
2411
  const milestone = this.hashmap[milestoneId];
2600
2412
  let mandatoryCount = 0;
2601
2413
  let completedMandatoryCount = 0;
2602
- console.log(`๐Ÿ” Checking mandatory content for milestone: ${milestoneId}`);
2603
2414
  // Check all items in hashmap that are direct children of this milestone (courses)
2604
2415
  for (const key of Object.keys(this.hashmap)) {
2605
2416
  const item = this.hashmap[key];
@@ -2623,25 +2434,12 @@ class AppTocService {
2623
2434
  if (isMandatory) {
2624
2435
  mandatoryCount++;
2625
2436
  const isCompleted = item.completionStatus === 2 || item.status === 2 || item.completionPercentage >= 100 || item.progress >= 100;
2626
- console.log(` ๐Ÿ“ Mandatory item: ${item.name || key}`, {
2627
- isMandatory: item.isMandatory,
2628
- completionStatus: item.completionStatus,
2629
- status: item.status,
2630
- completionPercentage: item.completionPercentage,
2631
- progress: item.progress,
2632
- isCompleted,
2633
- hasCompletionStatus: item.completionStatus !== undefined,
2634
- hasStatus: item.status !== undefined,
2635
- hasCompletionPercentage: item.completionPercentage !== undefined,
2636
- hasProgress: item.progress !== undefined
2637
- });
2638
2437
  if (isCompleted) {
2639
2438
  completedMandatoryCount++;
2640
2439
  }
2641
2440
  }
2642
2441
  }
2643
2442
  const allComplete = mandatoryCount === 0 || completedMandatoryCount >= mandatoryCount;
2644
- console.log(`๐Ÿ“Š Milestone ${milestoneId} mandatory status: ${completedMandatoryCount}/${mandatoryCount} complete = ${allComplete ? 'โœ… ALL COMPLETE' : 'โŒ INCOMPLETE'}`);
2645
2443
  return allComplete;
2646
2444
  }
2647
2445
  /**
@@ -2670,7 +2468,6 @@ class AppTocService {
2670
2468
  const milestone = this.hashmap[milestoneId];
2671
2469
  if (!milestone)
2672
2470
  return;
2673
- console.log(`Computing assessment locking for milestone: ${milestoneId}`);
2674
2471
  // Find assessment in this milestone
2675
2472
  let assessmentId = null;
2676
2473
  let assessment = null;
@@ -2686,12 +2483,10 @@ class AppTocService {
2686
2483
  if (isAssessment) {
2687
2484
  assessmentId = key;
2688
2485
  assessment = item;
2689
- console.log(`โœ… Found milestone assessment: ${item.name} (${key})`);
2690
2486
  break;
2691
2487
  }
2692
2488
  }
2693
2489
  if (!assessmentId || !assessment) {
2694
- console.log(`No assessment found in milestone ${milestoneId}`);
2695
2490
  return;
2696
2491
  }
2697
2492
  // Check if assessment is already completed - re-read from hashmap to get latest data
@@ -2703,7 +2498,6 @@ class AppTocService {
2703
2498
  // This ensures assessment is unlocked as soon as all mandatory courses are done
2704
2499
  let mandatoryCount = 0;
2705
2500
  let completedMandatoryCount = 0;
2706
- console.log(`[ASSESSMENT LOCK CHECK] Checking mandatory courses for milestone: ${milestoneId}`);
2707
2501
  for (const key of Object.keys(this.hashmap)) {
2708
2502
  const item = this.hashmap[key];
2709
2503
  if (key === assessmentId)
@@ -2731,44 +2525,22 @@ class AppTocService {
2731
2525
  item.status === 2 ||
2732
2526
  item.completionPercentage >= 100 ||
2733
2527
  item.progress >= 100;
2734
- console.log(` Course: ${item.name}`, {
2735
- isMandatory,
2736
- completionStatus: item.completionStatus,
2737
- status: item.status,
2738
- completionPercentage: item.completionPercentage,
2739
- progress: item.progress,
2740
- isCompleted
2741
- });
2742
2528
  if (isCompleted) {
2743
2529
  completedMandatoryCount++;
2744
2530
  }
2745
2531
  }
2746
2532
  }
2747
2533
  const allMandatoryComplete = mandatoryCount === 0 || completedMandatoryCount >= mandatoryCount;
2748
- console.log(`[ASSESSMENT LOCK CHECK] Summary:`, {
2749
- mandatoryCount,
2750
- completedMandatoryCount,
2751
- allMandatoryComplete,
2752
- assessmentCompleted,
2753
- willUnlock: assessmentCompleted || allMandatoryComplete
2754
- });
2755
2534
  if (assessmentCompleted || allMandatoryComplete) {
2756
2535
  this.hashmap[assessmentId].isAssessmentLocked = false;
2757
2536
  this.hashmap[assessmentId].milestoneAssessmentLocked = false;
2758
2537
  this.hashmap[assessmentId].assessmentLockMessage = '';
2759
- console.log(`โœ… Assessment ${assessmentId} is UNLOCKED (completed or all mandatory done)`);
2760
2538
  return;
2761
2539
  }
2762
2540
  // If not unlocked, lock the assessment
2763
2541
  this.hashmap[assessmentId].isAssessmentLocked = true;
2764
2542
  this.hashmap[assessmentId].milestoneAssessmentLocked = true;
2765
2543
  this.hashmap[assessmentId].assessmentLockMessage = 'This content is locked. Complete all mandatory items to unlock the assessment.';
2766
- console.log(`๐Ÿ”’ Assessment ${assessmentId} is LOCKED:`, {
2767
- mandatoryCount,
2768
- completedMandatoryCount,
2769
- isLocked: true,
2770
- milestoneAssessmentLocked: true
2771
- });
2772
2544
  }
2773
2545
  /**
2774
2546
  * Mark all children of a milestone as parent-locked or unlocked
@@ -2886,7 +2658,6 @@ class AppTocService {
2886
2658
  }
2887
2659
  }
2888
2660
  setTranscriptionData(data) {
2889
- // console.log('data--', data)
2890
2661
  this.transriptionDataSubject.next(data);
2891
2662
  }
2892
2663
  setActiveSubtitleLanguage(activeLang) {
@@ -6286,6 +6057,17 @@ i0.ษตษตngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
6286
6057
  * Certificate Service
6287
6058
  * Handles certificate-related operations
6288
6059
  */
6060
+ const urls = {
6061
+ HIERARCHY: 'course/v1/hierarchy',
6062
+ LEARNER_PREFIX: '/api/',
6063
+ PROXIES_PREFIX: '/apis/proxies/v8/',
6064
+ VALIDATE_CERTIFICATE: 'certreg/v1/certs/validate',
6065
+ DOWNLOAD_CERTIFICATE: (id) => `certreg/v2/certs/download/${id}`,
6066
+ DOWNLOAD_CERTIFICATE_v2: (id) => `apis/protected/v8/cohorts/course/batch/cert/download/${id}`,
6067
+ SEARCH_CERTIFICATE: 'certreg/v1/certs/search',
6068
+ VALIDATE_ENROLLMENT: 'cios-enroll/v1/validation',
6069
+ CONSENT_API: 'consent/v1/acknowledge',
6070
+ };
6289
6071
  class CertificateService {
6290
6072
  constructor(http) {
6291
6073
  this.http = http;
@@ -6301,7 +6083,7 @@ class CertificateService {
6301
6083
  * Download certificate
6302
6084
  */
6303
6085
  downloadCertificate(certId) {
6304
- return this.http.get(`/apis/public/v8/cert/download/${certId}`, {
6086
+ return this.http.get(`${urls.LEARNER_PREFIX}${urls.DOWNLOAD_CERTIFICATE(certId)}`, {
6305
6087
  responseType: 'blob'
6306
6088
  });
6307
6089
  }
@@ -6321,25 +6103,57 @@ class CertificateService {
6321
6103
  * Download certificate v2
6322
6104
  */
6323
6105
  downloadCertificate_v2(certId) {
6324
- return this.http.get(`/apis/public/v8/cert/v2/download/${certId}`, {
6325
- responseType: 'blob'
6326
- });
6106
+ return this.http.get(`${urls.DOWNLOAD_CERTIFICATE_v2(certId)}`);
6327
6107
  }
6328
6108
  /**
6329
6109
  * Validate enrollment eligibility
6330
6110
  */
6331
- validateEnrollmentEligibility(contentId, partnerId) {
6332
- return of({ eligible: true });
6111
+ validateEnrollmentEligibility(courseId, partnerId) {
6112
+ const option = {
6113
+ url: `${urls.PROXIES_PREFIX}${urls.VALIDATE_ENROLLMENT}`,
6114
+ data: {
6115
+ courseId,
6116
+ partnerId,
6117
+ },
6118
+ };
6119
+ return this.http.post(option.url, option.data);
6333
6120
  }
6334
6121
  /**
6335
6122
  * Submit consent for content
6336
6123
  */
6337
6124
  consentSubmit(request) {
6338
- return this.http.post(`${this.PROXY_SLAG_V8}/consent/v1/submit`, request);
6125
+ return this.http.post(`${this.PROXY_SLAG_V8}/consent/v1/acknowledge`, request);
6339
6126
  }
6340
6127
  downloadCertificate_v3(certId) {
6341
6128
  return this.http.get(`/apis/protected/v8/cohorts/course/batch/cert/download/${certId}`);
6342
6129
  }
6130
+ validateCertificate(data) {
6131
+ const option = {
6132
+ data,
6133
+ // url: `${urls.PROXIES_PREFIX}learner/${urls.VALIDATE_CERTIFICATE}`,
6134
+ url: `${urls.LEARNER_PREFIX}${urls.VALIDATE_CERTIFICATE}`,
6135
+ };
6136
+ return this.http.post(option.url, option.data);
6137
+ }
6138
+ searchCertificate(recipientId) {
6139
+ const option = {
6140
+ url: `${urls.LEARNER_PREFIX}${urls.SEARCH_CERTIFICATE}`,
6141
+ data: {
6142
+ request: {
6143
+ _source: ['data.badge.issuer.name', 'pdfUrl', 'data.issuedOn', 'data.badge.name'],
6144
+ query: {
6145
+ bool: {
6146
+ must: [{
6147
+ match_phrase: { 'recipient.id': recipientId },
6148
+ }],
6149
+ },
6150
+ },
6151
+ size: 50,
6152
+ },
6153
+ },
6154
+ };
6155
+ return this.http.post(option.url, option.data);
6156
+ }
6343
6157
  static { this.ษตfac = i0.ษตษตngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CertificateService, deps: [{ token: i1.HttpClient }], target: i0.ษตษตFactoryTarget.Injectable }); }
6344
6158
  static { this.ษตprov = i0.ษตษตngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CertificateService, providedIn: 'root' }); }
6345
6159
  }
@@ -6511,18 +6325,11 @@ class AppTocContentCardV2Component {
6511
6325
  // Subscribe to hashmap updates to recompute cached properties when progress changes
6512
6326
  this.hashmapUpdatedSubscription = this.appTocSvc.hashmapUpdated$.subscribe((update) => {
6513
6327
  if (update && update.hashmap) {
6514
- console.log('๐Ÿ“ก [CONTENT CARD] Received hashmap update for:', this.content?.identifier, this.content?.name);
6515
6328
  // IMPORTANT: Update hierarchyMapData with the latest hashmap from the service
6516
6329
  // This ensures the component uses the updated data, not the stale @Input reference
6517
6330
  this.hierarchyMapData = update.hashmap;
6518
6331
  const prevLockState = this._cachedIsMilestoneLocked;
6519
6332
  this.computeAllCachedProperties();
6520
- console.log('๐Ÿ“ก [CONTENT CARD] Lock state change:', {
6521
- id: this.content?.identifier,
6522
- previousLockState: prevLockState,
6523
- newLockState: this._cachedIsMilestoneLocked,
6524
- isMilestone: this._cachedIsMilestone
6525
- });
6526
6333
  // Force Angular change detection to update the view
6527
6334
  this.cdr.detectChanges();
6528
6335
  }
@@ -6650,22 +6457,14 @@ class AppTocContentCardV2Component {
6650
6457
  }
6651
6458
  // Check if hashmap has pre-computed locking status (preferred - computed by service)
6652
6459
  const hashData = this.hierarchyMapData && this.hierarchyMapData[this.content.identifier];
6653
- console.log(`๐Ÿ”’ [MILESTONE LOCK CHECK] ${this.content.identifier} (${this.content.name}):`, {
6654
- hasHashData: !!hashData,
6655
- computedIsLocked: hashData?.computedIsLocked,
6656
- hasComputedIsLocked: hashData?.computedIsLocked !== undefined,
6657
- contentIsLocked: this.content.isLocked
6658
- });
6659
6460
  // CRITICAL: Only use computedIsLocked from hashmap - this is the SINGLE SOURCE OF TRUTH
6660
6461
  // The service computes this value based on pre-assessment/milestone completion
6661
6462
  if (hashData && hashData.computedIsLocked !== undefined) {
6662
- console.log(` โœ… Using hashmap computedIsLocked: ${hashData.computedIsLocked}`);
6663
6463
  return hashData.computedIsLocked;
6664
6464
  }
6665
6465
  // IMPORTANT: If no computedIsLocked value exists, default to LOCKED
6666
6466
  // This ensures milestones stay locked until the service explicitly unlocks them
6667
6467
  // DO NOT use this.content.isLocked as it may be false by default from API
6668
- console.log(` โš ๏ธ No computedIsLocked in hashmap - defaulting to LOCKED`);
6669
6468
  return true;
6670
6469
  }
6671
6470
  computeIsParentMilestoneLocked() {
@@ -6733,40 +6532,19 @@ class AppTocContentCardV2Component {
6733
6532
  // or fallback to content.parent if hashmap entry doesn't exist
6734
6533
  const contentHashData = this.hierarchyMapData[this.content.identifier];
6735
6534
  const parentId = contentHashData?.parent || this.content.parent;
6736
- console.log(`๐Ÿ” computeIsMilestoneAssessment for "${this.content.name}" (${this.content.identifier}):`, {
6737
- contentId: this.content.identifier,
6738
- primaryCategory: this.content.primaryCategory,
6739
- mimeType: this.content.mimeType,
6740
- contentParent: this.content.parent,
6741
- hashmapParent: contentHashData?.parent,
6742
- resolvedParentId: parentId,
6743
- hasParentData: !!this.hierarchyMapData[parentId]
6744
- });
6745
6535
  if (parentId && this.hierarchyMapData[parentId]) {
6746
6536
  const parentData = this.hierarchyMapData[parentId];
6747
- console.log(` Parent details:`, {
6748
- parentId: parentId,
6749
- parentName: parentData?.name,
6750
- parentPrimaryCategory: parentData?.primaryCategory,
6751
- parentIsMilestone: parentData?.isMilestone,
6752
- parentCourseCategory: parentData?.courseCategory,
6753
- });
6754
6537
  // Check if DIRECT parent is a milestone - ONLY this case
6755
6538
  const isParentMilestone = parentData.isMilestone ||
6756
6539
  parentData.primaryCategory === 'Milestone' ||
6757
6540
  parentData.courseCategory === 'Milestone';
6758
6541
  if (isParentMilestone) {
6759
- console.log(` โœ… Result: IS a milestone assessment (direct child of milestone)`);
6760
6542
  return true;
6761
6543
  }
6762
- console.log(` โŒ Result: NOT a milestone assessment (parent is ${parentData.primaryCategory}, not a Milestone)`);
6763
6544
  // DO NOT check grandparent - course assessments inside courses within milestones
6764
6545
  // should NOT be treated as milestone assessments
6765
6546
  return false;
6766
6547
  }
6767
- else {
6768
- console.log(` โš ๏ธ No parent data found for ${parentId}`);
6769
- }
6770
6548
  return false;
6771
6549
  }
6772
6550
  /**
@@ -6784,13 +6562,7 @@ class AppTocContentCardV2Component {
6784
6562
  }
6785
6563
  // Only apply to assessments that are DIRECT children of milestones
6786
6564
  const isMilestoneAssessment = this._cachedIsMilestoneAssessment || this.computeIsMilestoneAssessment();
6787
- console.log(`๐Ÿ”’ computeIsMilestoneAssessmentLocked for "${this.content?.name}":`, {
6788
- isMilestoneAssessment,
6789
- _cachedIsMilestoneAssessment: this._cachedIsMilestoneAssessment,
6790
- courseCategory: this.baseContentReadData?.courseCategory,
6791
- });
6792
6565
  if (!isMilestoneAssessment) {
6793
- console.log(`๐Ÿ”“ "${this.content?.name}" NOT locked - not a milestone assessment`);
6794
6566
  return false;
6795
6567
  }
6796
6568
  // Check if hashmap has pre-computed assessment locking status
@@ -6912,8 +6684,6 @@ class AppTocContentCardV2Component {
6912
6684
  if (shouldRecomputeCache) {
6913
6685
  this.computeAllCachedProperties();
6914
6686
  }
6915
- // console.log('pre assessment content---', this.content)
6916
- // console.log('this.hierarchyMapData---', this.hierarchyMapData)
6917
6687
  }
6918
6688
  check(content) {
6919
6689
  if (this.expandActive) {
@@ -7127,7 +6897,6 @@ class AppTocContentCardV2Component {
7127
6897
  // const total = localContentData.leafNodes.reduce((sum: number, childId: string) => {
7128
6898
  // return sum + Number(this.hierarchyMapData[childId].completionPercentage || 0)
7129
6899
  // }, 0)
7130
- // console.log('total ', total)
7131
6900
  // if(total > 0) {
7132
6901
  // this.hierarchyMapData[identifier]['completionPercentage'] = total / _.toInteger(_.get(this.hierarchyMapData[identifier], 'leafNodesCount'))
7133
6902
  // }
@@ -7149,8 +6918,6 @@ class AppTocContentCardV2Component {
7149
6918
  return '';
7150
6919
  }
7151
6920
  getCompletionPercentage(identifier) {
7152
- // console.log('getCompletionPercentage', identifier)
7153
- // console.log('this.hierarchyMapData[identifier] : ', this.hierarchyMapData[identifier])
7154
6921
  // const item = this.updateChildParentMap(identifier)
7155
6922
  let percent = this.hierarchyMapData && this.hierarchyMapData[identifier] && this.hierarchyMapData[identifier].completionPercentage || 0;
7156
6923
  return this.roundIfDecimal(percent);
@@ -7162,7 +6929,6 @@ class AppTocContentCardV2Component {
7162
6929
  return value;
7163
6930
  }
7164
6931
  getCompletionStatus(identifier) {
7165
- // console.log('getCompletionStatus')
7166
6932
  // const item = this.updateChildParentMap(identifier)
7167
6933
  return this.hierarchyMapData && this.hierarchyMapData[identifier] && this.hierarchyMapData[identifier].completionStatus;
7168
6934
  }
@@ -7365,7 +7131,6 @@ class AppTocContentCardV2Component {
7365
7131
  }
7366
7132
  }
7367
7133
  });
7368
- console.log('Milestone content check:', { allMandatoryComplete, hasAssessment, assessmentComplete });
7369
7134
  // Milestone is complete if assessment is complete (mandatory courses optional based on requirements)
7370
7135
  return hasAssessment ? assessmentComplete : allMandatoryComplete;
7371
7136
  }
@@ -7382,7 +7147,6 @@ class AppTocContentCardV2Component {
7382
7147
  // Extract milestone number from ID (M1 -> 1, M2 -> 2, etc.)
7383
7148
  const milestoneNum = parseInt(milestoneId.replace(/\D/g, '')) || 0;
7384
7149
  const requiredCompletedAssessments = milestoneNum - 1; // For M2, need 1; for M3, need 2
7385
- console.log(`Milestone ${milestoneId} (num: ${milestoneNum}) requires ${requiredCompletedAssessments} completed assessments`);
7386
7150
  if (requiredCompletedAssessments <= 0) {
7387
7151
  return true; // First milestone, no requirements
7388
7152
  }
@@ -7400,14 +7164,9 @@ class AppTocContentCardV2Component {
7400
7164
  const hasParent = item.parent && item.parent !== learningPathwayId;
7401
7165
  if (hasParent) {
7402
7166
  completedMilestoneAssessmentCount++;
7403
- console.log(`Found completed MILESTONE assessment: ${key}`, item);
7404
- }
7405
- else {
7406
- console.log(`Skipping root-level/pre-enrollment assessment: ${key}`);
7407
7167
  }
7408
7168
  }
7409
7169
  }
7410
- console.log(`Total completed MILESTONE assessments: ${completedMilestoneAssessmentCount}, Required: ${requiredCompletedAssessments}`);
7411
7170
  // If we have enough completed milestone assessments, unlock this milestone
7412
7171
  return completedMilestoneAssessmentCount >= requiredCompletedAssessments;
7413
7172
  }
@@ -7553,8 +7312,6 @@ class AppTocContentCardV2Component {
7553
7312
  }
7554
7313
  const pageId = `app/toc/pageId/${content.identifier}`;
7555
7314
  this.resourceDownloadHelperSvc.downloadPDF(content, pageId);
7556
- console.log('content', content);
7557
- console.log('baseContent', this.baseContentReadData);
7558
7315
  }
7559
7316
  /**
7560
7317
  * View milestone achievement - calls the achievement API and shows the result
@@ -7570,7 +7327,6 @@ class AppTocContentCardV2Component {
7570
7327
  // Get user ID from ConfigurationsService
7571
7328
  const userId = this.configSvc?.userProfile?.userId;
7572
7329
  if (!userId) {
7573
- console.error('User ID not found');
7574
7330
  return;
7575
7331
  }
7576
7332
  // Extract milestone ID (e.g., "m1", "m2") from the content name or index
@@ -7585,7 +7341,6 @@ class AppTocContentCardV2Component {
7585
7341
  this.appTocSvc.generateMilestoneAchievement(userId, courseId, this.batchId, milestoneId).subscribe({
7586
7342
  next: (response) => {
7587
7343
  this.achievementLoading = false;
7588
- console.log('Achievement generated successfully:', response);
7589
7344
  // Show achievement dialog or handle response
7590
7345
  if (response && response.result) {
7591
7346
  // Open a dialog to show the achievement
@@ -7609,7 +7364,6 @@ class AppTocContentCardV2Component {
7609
7364
  verticalPosition: 'bottom',
7610
7365
  panelClass: ['error-snackbar']
7611
7366
  });
7612
- console.error('Error generating achievement:', error);
7613
7367
  }
7614
7368
  });
7615
7369
  }
@@ -9227,13 +8981,11 @@ class ContentTocComponent {
9227
8981
  }
9228
8982
  ngOnInit() {
9229
8983
  if (this.configService.iGOTAIConfig && this.configService.iGOTAIConfig?.aiTutor && this.configService.iGOTAIConfig?.aiTutor?.all) {
9230
- // console.log('this.contentReadData--', this.route.snapshot.data)
9231
8984
  this.enableAITutorFlag = this.onlyscormAssessmentExists(this.route.snapshot?.data?.content?.data?.children, 'mimeType', ['application/vnd.ekstep.html-archive', 'application/vnd.sunbird.questionset', 'application/json', 'text/x-url']);
9232
8985
  // this.enableAITutorFlag = true
9233
8986
  }
9234
8987
  else if (this.configService.iGOTAIConfig && this.configService.iGOTAIConfig?.aiTutor && this.configService.iGOTAIConfig?.aiTutor?.forOrg && this.configService.iGOTAIConfig.aiTutor?.forOrg?.length &&
9235
8988
  this.configService.iGOTAIConfig?.aiTutor?.forOrg.includes(this.configService.userProfile?.rootOrgId)) {
9236
- // console.log('this.contentReadData--', this.route.snapshot.data)
9237
8989
  this.enableAITutorFlag = this.onlyscormAssessmentExists(this.route.snapshot?.data?.content?.data?.children, 'mimeType', ['application/vnd.ekstep.html-archive', 'application/vnd.sunbird.questionset', 'application/json', 'text/x-url']);
9238
8990
  // this.enableAITutorFlag = true
9239
8991
  }
@@ -9241,22 +8993,18 @@ class ContentTocComponent {
9241
8993
  this.enableAITutorFlag = false;
9242
8994
  }
9243
8995
  if (this.configService.iGOTAIConfig && this.configService.iGOTAIConfig?.transcription?.all) {
9244
- // console.log('in')
9245
8996
  // this.resourceIdentifier$ = this.tocSvc.transriptionIdentifier.subscribe((value:any)=>{
9246
- // // console.log('resource identifier', value)
9247
8997
  // if(value && value?.identifier) {
9248
8998
  // this.resourceIdentifier = value?.identifier //value?.identifier // do_1138891198489067521147
9249
8999
  // this.parseVTT()
9250
9000
  // }
9251
9001
  // })
9252
9002
  this.subTitles$ = this.tocSvc.transcriptionData$.subscribe((value) => {
9253
- // console.log('value', value)
9254
9003
  this.keywordToHighlight = value;
9255
9004
  });
9256
9005
  this.transriptionLanguageSub = this.tocSvc.transriptionActiveLanguageDataObject$
9257
9006
  .pipe(tap((langvalue) => console.log('tap langvalue:', langvalue)))
9258
9007
  .subscribe((langvalue) => {
9259
- // console.log('langValue', langvalue);
9260
9008
  if (langvalue) {
9261
9009
  // this.renderSelectedLanguageTranscription();
9262
9010
  }
@@ -9265,22 +9013,18 @@ class ContentTocComponent {
9265
9013
  }
9266
9014
  else if (this.configService.iGOTAIConfig && this.configService.iGOTAIConfig?.transcription && this.configService.iGOTAIConfig?.transcription?.forOrg && this.configService.iGOTAIConfig?.transcription?.forOrg?.length &&
9267
9015
  this.configService.iGOTAIConfig?.transcription?.forOrg?.includes(this.configService.userProfile?.rootOrgId)) {
9268
- // console.log('in')
9269
9016
  // this.resourceIdentifier$ = this.tocSvc.transriptionIdentifier.subscribe((value:any)=>{
9270
- // // console.log('resource identifier', value)
9271
9017
  // if(value && value?.identifier) {
9272
9018
  // this.resourceIdentifier = value?.identifier //value?.identifier // do_1138891198489067521147
9273
9019
  // this.parseVTT()
9274
9020
  // }
9275
9021
  // })
9276
9022
  this.subTitles$ = this.tocSvc.transcriptionData$.subscribe((value) => {
9277
- // console.log('value', value)
9278
9023
  this.keywordToHighlight = value;
9279
9024
  });
9280
9025
  this.transriptionLanguageSub = this.tocSvc.transriptionActiveLanguageDataObject$
9281
9026
  .pipe(tap((langvalue) => console.log('tap langvalue:', langvalue)))
9282
9027
  .subscribe((langvalue) => {
9283
- // console.log('langValue', langvalue);
9284
9028
  if (langvalue) {
9285
9029
  // this.renderSelectedLanguageTranscription();
9286
9030
  }
@@ -9348,7 +9092,6 @@ class ContentTocComponent {
9348
9092
  this.enableTranscriptionFlag = false;
9349
9093
  }
9350
9094
  if (this.configService.iGOTAIConfig && this.configService.iGOTAIConfig?.aiTutor && this.configService.iGOTAIConfig.aiTutor?.all) {
9351
- // console.log('this.contentReadData--', this.route.snapshot.data)
9352
9095
  this.enableAITutorFlag = this.onlyscormAssessmentExists(this.content?.children, 'mimeType', ['application/vnd.ekstep.html-archive', 'application/vnd.sunbird.questionset', 'application/json', 'text/x-url']);
9353
9096
  // this.enableAITutorFlag = true
9354
9097
  }
@@ -9375,7 +9118,6 @@ class ContentTocComponent {
9375
9118
  if (this.config && this.config.discussWidgetData) {
9376
9119
  this.discussWidgetData = this.config.discussWidgetData;
9377
9120
  if (this.baseContentReadData && this.baseContentReadData.identifier) {
9378
- // console.log('this.content.identifier', this.content.identifier)
9379
9121
  if (!this.discussWidgetData.newCommentSection.commentTreeData.entityId) {
9380
9122
  this.discussWidgetData.newCommentSection.commentTreeData.entityId = this.baseContentReadData.identifier;
9381
9123
  }
@@ -9499,8 +9241,6 @@ class ContentTocComponent {
9499
9241
  this.tabChangeValue = event.tab;
9500
9242
  this.selectedTabIndex = event.index;
9501
9243
  this.loadCheckService.componentLoaded(true);
9502
- // console.log('event', event)
9503
- // console.log('this.content', this.viewerDataSvc?.resourceId)
9504
9244
  if (event && event.tab.textLabel === 'AI Tutor') {
9505
9245
  this.showAITutorPopup = true;
9506
9246
  }
@@ -9562,8 +9302,6 @@ class ContentTocComponent {
9562
9302
  }
9563
9303
  this.resumeDataLink = viewerRouteGenerator(resumeDataV2.identifier, resumeDataV2.mimeType, this.content.identifier, this.content.contentType, this.forPreview, 'Learning Resource', this.getBatchId(), this.content.name);
9564
9304
  this.actionSVC.setUpdateCompGroupO = this.resumeDataLink;
9565
- // console.log('this.resumeDataLink',this.resumeDataLink)
9566
- // console.log('this.actionSVC', this.actionSVC)
9567
9305
  this.router.navigate([this.resumeDataLink.url], {
9568
9306
  queryParams: {
9569
9307
  ...this.resumeDataLink.queryParams,
@@ -9671,10 +9409,8 @@ class ContentTocComponent {
9671
9409
  this.vttLangArr = data[0]['transcription_urls'];
9672
9410
  this.enableTranscriptionFlag = true;
9673
9411
  // let url = data[0]['transcription_urls'][0]['uri']
9674
- // console.log('this.vttLangArr--',this.vttLangArr)
9675
9412
  this.transcriptionActiveLanguage = this.vttLangArr && this.vttLangArr.length && this.vttLangArr[0] && this.vttLangArr[0]['default_lang'] ? 'en' : 'en';
9676
9413
  this.defaultTranscriptLanguage = this.vttLangArr && this.vttLangArr.length && this.vttLangArr[0] && this.vttLangArr[0]['default_lang'] ? 'en' : 'en';
9677
- // console.log('this.transcriptionActiveLanguage--', this.transcriptionActiveLanguage)
9678
9414
  let selectedTranscriptionStyle = this.vttLangArr.filter((item) => {
9679
9415
  return item?.label === this.transcriptionActiveLanguage;
9680
9416
  });
@@ -9684,7 +9420,6 @@ class ContentTocComponent {
9684
9420
  else {
9685
9421
  this.selectedTranscriptionStyle = this.vttLangArr[0];
9686
9422
  }
9687
- // console.log('this.selectedTranscriptionStyle--', this.selectedTranscriptionStyle)
9688
9423
  const filteredArr = this.vttLangArr.filter((item) => item.label === this.transcriptionActiveLanguage);
9689
9424
  let url = filteredArr.length > 0 ? filteredArr[0].uri : null;
9690
9425
  //let url = this.vttLangArr.filter((item: any) => item.label === this.transcriptionActiveLanguage)[0]['uri']
@@ -9693,12 +9428,6 @@ class ContentTocComponent {
9693
9428
  let blocks = file.getBlocks();
9694
9429
  this.subTitles = blocks;
9695
9430
  }
9696
- // console.log('this.vttLangArr--',this.vttLangArr)
9697
- // if(this.vttLangArr && this.vttLangArr.length) {
9698
- // this.transcriptionActiveLanguage = this.vttLangArr[0]['label']
9699
- // } else {
9700
- // this.transcriptionActiveLanguage = this.vttLangArr[0]['default_lang']
9701
- // }
9702
9431
  this.tocSvc.changeTranscriptionLanguageEvent.next({ activeLang: this.transcriptionActiveLanguage, langData: this.vttLangArr, loadPlayer: true });
9703
9432
  }
9704
9433
  else {
@@ -9754,8 +9483,6 @@ class ContentTocComponent {
9754
9483
  onlyscormAssessmentExists(data, key, value) {
9755
9484
  for (let i = 0; i < data?.length; i++) {
9756
9485
  if (data[i] && data[i]['children'] && data[i]['children'].length) {
9757
- // this.totalResource = this.totalResource + 1
9758
- // console.log('in children')
9759
9486
  this.onlyscormAssessmentExists(data[i]?.children, key, value);
9760
9487
  }
9761
9488
  else {
@@ -12444,14 +12171,9 @@ class ViewerUtilService {
12444
12171
  this.http
12445
12172
  .patch(`${this.API_ENDPOINTS.PROGRESS_UPDATE}/${contentId}`, req)
12446
12173
  .subscribe(noop, noop);
12447
- console.log(`๐Ÿ”„ [PROGRESS UPDATE] realTimeProgressUpdate called for ${contentId}`);
12448
- console.log(` Status: ${req.request.contents[0].status}, Percentage: ${req.request.contents[0].completionPercentage}`);
12449
- console.log(` Hashmap has contentId: ${!!this.tocSvc.hashmap[contentId]}`);
12450
12174
  if (this.tocSvc.hashmap[contentId]) {
12451
12175
  const currentStatus = this.tocSvc.hashmap[contentId]['completionStatus'];
12452
- console.log(` Current completionStatus in hashmap: ${currentStatus}`);
12453
12176
  if (!currentStatus || currentStatus < 2) {
12454
- console.log(` โœ… Updating hashmap for ${contentId}`);
12455
12177
  this.tocSvc.hashmap[contentId]['completionPercentage'] = req.request.contents[0].completionPercentage;
12456
12178
  this.tocSvc.hashmap[contentId]['completionStatus'] = Number(req.request.contents[0].status) || 0;
12457
12179
  this.tocSvc.hashmap = { ...this.tocSvc.hashmap };
@@ -12460,12 +12182,6 @@ class ViewerUtilService {
12460
12182
  // Emit to trigger viewer component refresh for Learning Pathways
12461
12183
  this.markAsCompleteSubject.next(true);
12462
12184
  }
12463
- else {
12464
- console.log(` โญ๏ธ Skipping update - content already completed (status=${currentStatus})`);
12465
- }
12466
- }
12467
- else {
12468
- console.log(` โš ๏ธ ContentId ${contentId} not found in hashmap - cannot update progress`);
12469
12185
  }
12470
12186
  }
12471
12187
  else {
@@ -12663,14 +12379,9 @@ class ViewerUtilService {
12663
12379
  this.http
12664
12380
  .patch(`${this.API_ENDPOINTS.PROGRESS_UPDATE}/${contentId}`, req)
12665
12381
  .subscribe(noop, noop);
12666
- console.log(`๐Ÿ”„ [PROGRESS UPDATE QUIZ] realTimeProgressUpdateQuiz called for ${contentId}`);
12667
- console.log(` Status: ${req.request.contents[0].status}, Percentage: ${req.request.contents[0].completionPercentage}`);
12668
- console.log(` Hashmap exists: ${!!this.tocSvc.hashmap}, Hashmap has contentId: ${!!(this.tocSvc.hashmap && this.tocSvc.hashmap[contentId])}`);
12669
12382
  if (this.tocSvc.hashmap && this.tocSvc.hashmap[contentId] && req.request.contents[0]) {
12670
12383
  const currentStatus = this.tocSvc.hashmap[contentId]['completionStatus'];
12671
- console.log(` Current completionStatus in hashmap: ${currentStatus}`);
12672
12384
  if (!currentStatus || currentStatus < 2) {
12673
- console.log(` โœ… Updating hashmap for ${contentId}`);
12674
12385
  this.tocSvc.hashmap[contentId]['completionPercentage'] = req.request.contents[0].completionPercentage;
12675
12386
  this.tocSvc.hashmap[contentId]['completionStatus'] = Number(req.request.contents[0].status) || 0;
12676
12387
  this.tocSvc.hashmap = { ...this.tocSvc.hashmap };
@@ -12681,12 +12392,6 @@ class ViewerUtilService {
12681
12392
  // Emit to trigger viewer component refresh for Learning Pathways
12682
12393
  this.markAsCompleteSubject.next(true);
12683
12394
  }
12684
- else {
12685
- console.log(` โญ๏ธ Skipping update - content already completed (status=${currentStatus})`);
12686
- }
12687
- }
12688
- else {
12689
- console.log(` โš ๏ธ Cannot update hashmap - hashmap or contentId missing`);
12690
12395
  }
12691
12396
  }
12692
12397
  else {
@@ -12750,15 +12455,6 @@ class ViewerUtilService {
12750
12455
  return this.http.get(`/apis/proxies/v8/action/content/v3/hierarchy/${id}?mode=${type}`);
12751
12456
  }
12752
12457
  updateContentHashMapForAssesstent(contentId, contentProgress) {
12753
- console.log('๐Ÿ“Š [UPDATE HASHMAP] Updating assessment in hashmap:', {
12754
- contentId,
12755
- incomingProgress: contentProgress,
12756
- currentHashmapData: this.tocSvc.hashmap[contentId] ? {
12757
- completionPercentage: this.tocSvc.hashmap[contentId]['completionPercentage'],
12758
- completionStatus: this.tocSvc.hashmap[contentId]['completionStatus'],
12759
- status: this.tocSvc.hashmap[contentId]['status']
12760
- } : 'not found'
12761
- });
12762
12458
  if (this.tocSvc.hashmap[contentId]) {
12763
12459
  const currentStatus = this.tocSvc.hashmap[contentId]['completionStatus'] || 0;
12764
12460
  const newStatus = Number(contentProgress.status) || 0;
@@ -12767,29 +12463,15 @@ class ViewerUtilService {
12767
12463
  this.tocSvc.hashmap[contentId]['completionPercentage'] = contentProgress.completionPercentage;
12768
12464
  this.tocSvc.hashmap[contentId]['completionStatus'] = newStatus;
12769
12465
  this.tocSvc.hashmap[contentId]['status'] = newStatus;
12770
- console.log('โœ… [UPDATE HASHMAP] Updated assessment:', {
12771
- contentId,
12772
- name: this.tocSvc.hashmap[contentId]['name'],
12773
- completionPercentage: contentProgress.completionPercentage,
12774
- completionStatus: newStatus,
12775
- status: newStatus
12776
- });
12777
12466
  // Create new hashmap reference for Angular change detection
12778
12467
  this.tocSvc.hashmap = { ...this.tocSvc.hashmap };
12779
12468
  // Trigger milestone lock recomputation - it will emit hashmapUpdated with both progress and lock changes
12780
12469
  if (this.tocSvc.triggerMilestoneLockUpdate) {
12781
- console.log('๐Ÿ”„ [UPDATE HASHMAP] Triggering milestone lock update after assessment update');
12782
12470
  this.tocSvc.triggerMilestoneLockUpdate();
12783
12471
  }
12784
12472
  // Emit to trigger viewer component refresh for Learning Pathways
12785
12473
  this.markAsCompleteSubject.next(true);
12786
12474
  }
12787
- else {
12788
- console.log('โ„น๏ธ [UPDATE HASHMAP] Skipping update - already complete or lower status');
12789
- }
12790
- }
12791
- else {
12792
- console.log('โš ๏ธ [UPDATE HASHMAP] Content not found in hashmap:', contentId);
12793
12475
  }
12794
12476
  }
12795
12477
  getFormById(formId) {
@@ -12870,8 +12552,6 @@ class ViewerUtilService {
12870
12552
  // Emit to trigger viewer component refresh for Learning Pathways
12871
12553
  this.markAsCompleteSubject.next(true);
12872
12554
  }
12873
- // console.log('Updated hashmap:', this.tocSvc.hashmap)
12874
- // console.log('this.tocSvc.hashmap---', this.tocSvc.hashmap)
12875
12555
  }
12876
12556
  else {
12877
12557
  req = {};
@@ -12905,13 +12585,10 @@ class ViewerUtilService {
12905
12585
  .patch(`${this.API_ENDPOINTS.PRE_ASSESSMENT_STATE_UPDATE}`, req)
12906
12586
  .subscribe(noop, noop);
12907
12587
  }
12908
- console.log('๐ŸŽฏ [PRE-ASSESSMENT QUIZ] Updating progress for:', contentId);
12909
- console.log(' Status:', status, 'Completion:', req.request.contents[0].completionPercentage);
12910
12588
  // Update hashmap - create entry if it doesn't exist
12911
12589
  if (this.tocSvc.hashmap) {
12912
12590
  if (!this.tocSvc.hashmap[contentId]) {
12913
12591
  // Create new entry for pre-assessment if it doesn't exist
12914
- console.log(' Creating new hashmap entry for pre-assessment');
12915
12592
  this.tocSvc.hashmap[contentId] = {
12916
12593
  identifier: contentId,
12917
12594
  completionPercentage: req.request.contents[0].completionPercentage,
@@ -12922,16 +12599,13 @@ class ViewerUtilService {
12922
12599
  }
12923
12600
  else {
12924
12601
  // Update existing entry
12925
- console.log(' Updating existing hashmap entry');
12926
12602
  this.tocSvc.hashmap[contentId]['completionPercentage'] = req.request.contents[0].completionPercentage;
12927
12603
  this.tocSvc.hashmap[contentId]['completionStatus'] = Number(req.request.contents[0].status) || 0;
12928
12604
  this.tocSvc.hashmap[contentId]['status'] = Number(req.request.contents[0].status) || 0;
12929
12605
  }
12930
- console.log(' Hashmap entry after update:', this.tocSvc.hashmap[contentId]);
12931
12606
  this.tocSvc.hashmap = { ...this.tocSvc.hashmap };
12932
12607
  // ALWAYS trigger milestone lock recomputation when pre-assessment completes
12933
12608
  // This ensures milestone 1 unlocks immediately after pre-assessment completion
12934
- console.log('๐Ÿ”„ [PRE-ASSESSMENT QUIZ] Triggering milestone lock update');
12935
12609
  if (this.tocSvc.triggerMilestoneLockUpdate) {
12936
12610
  this.tocSvc.triggerMilestoneLockUpdate();
12937
12611
  }
@@ -15878,19 +15552,9 @@ class AppTocV2Service {
15878
15552
  contentHeirarchy['preliminaryAssessmentDetail'].parent = contentHeirarchy.identifier;
15879
15553
  // Mark this as the pre-assessment for milestone locking logic
15880
15554
  contentHeirarchy['preliminaryAssessmentDetail'].isPreAssessment = true;
15881
- console.log('๐Ÿ” [CONSTRUCT HIERARCHY] Setting isPreAssessment=true on preliminaryAssessmentDetail:', {
15882
- id: contentHeirarchy['preliminaryAssessmentDetail'].identifier,
15883
- name: contentHeirarchy['preliminaryAssessmentDetail'].name,
15884
- isPreAssessment: contentHeirarchy['preliminaryAssessmentDetail'].isPreAssessment,
15885
- parent: contentHeirarchy['preliminaryAssessmentDetail'].parent,
15886
- primaryCategory: contentHeirarchy['preliminaryAssessmentDetail'].primaryCategory
15887
- });
15888
15555
  contentHeirarchy['children'].push(contentHeirarchy['preliminaryAssessmentDetail']);
15889
15556
  leafNodes.push(contentReadData?.preliminaryAssessment || contentReadData?.preliminaryAssessmentDetail?.identifier);
15890
15557
  }
15891
- else {
15892
- console.log('โš ๏ธ [CONSTRUCT HIERARCHY] No preliminaryAssessmentDetail found in contentReadData');
15893
- }
15894
15558
  // Track milestone index for proper locking logic
15895
15559
  // All milestones are locked by default - unlocking is computed based on progress
15896
15560
  let milestoneIndex = 0;
@@ -16078,15 +15742,6 @@ class AppTocV2Service {
16078
15742
  node.completionPercentage = progress;
16079
15743
  node.completionStatus = status;
16080
15744
  node.status = status;
16081
- console.log(`Direct enrollment found for ${node.identifier}:`, {
16082
- completionPercentage: progress,
16083
- completionStatus: status,
16084
- enrollmentData: {
16085
- progress: enrollment.progress,
16086
- completionPercentage: enrollment.completionPercentage,
16087
- status: enrollment.status
16088
- }
16089
- });
16090
15745
  return;
16091
15746
  }
16092
15747
  // Try both contentId and collectionId as the API response may use either field
@@ -16118,11 +15773,6 @@ class AppTocV2Service {
16118
15773
  node.completionStatus = 0;
16119
15774
  node.status = 0;
16120
15775
  }
16121
- console.log(`Updated node progress for ${node.identifier}:`, {
16122
- completionStatus: node.completionStatus,
16123
- completionPercentage: node.completionPercentage,
16124
- status: node.status
16125
- });
16126
15776
  }
16127
15777
  updateCourseProgress(course, parentContentIdentifier, enrollmentListData) {
16128
15778
  const enrollment = this.findEnrollment(enrollmentListData, course?.identifier);
@@ -21635,7 +21285,6 @@ class AppTocHomeV2Component {
21635
21285
  // CRITICAL: For Learning Pathways, compute milestone locking status after enrollment
21636
21286
  // This ensures milestones are properly locked until pre-assessment is completed
21637
21287
  if (this.baseContentReadData?.courseCategory === 'Learning Pathway') {
21638
- console.log('๐Ÿ” [ENROLLMENT] Computing milestone locking for Learning Pathway after enrollment');
21639
21288
  this.tocSvc.callHirarchyProgressHashmap(this.content);
21640
21289
  this.tocSvc.computeMilestoneLockingStatus(true);
21641
21290
  this.syncMilestoneLockStatus();
@@ -22172,10 +21821,8 @@ class AppTocHomeV2Component {
22172
21821
  // Recompute milestone locking status from existing hashmap
22173
21822
  // The hashmap is already updated with latest progress via hashmap update subscription
22174
21823
  this.tocSvc.computeMilestoneLockingStatus(isEnrolled);
22175
- console.log('๐Ÿ”“ Milestone locking recomputed from hashmap. Enrolled:', isEnrolled);
22176
21824
  // Sync lock status from hashmap to content tree
22177
21825
  this.syncMilestoneLockStatus();
22178
- console.log('โœ… Milestone locks refreshed from hashmap');
22179
21826
  }
22180
21827
  catch (error) {
22181
21828
  console.error('โŒ Error in refreshEnrollmentAndProgress:', error);