All files / web/src/utils skillDisplay.ts

100% Statements 105/105
88.88% Branches 16/18
100% Functions 5/5
100% Lines 105/105

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 1061x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 3x 3x 3x 3x 3x 4x 2x 2x 4x 4x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 3x 3x 3x 3x 3x 1x 1x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 3x 3x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 2x 1x 1x 1x 9x 9x 1x 1x  
/**
 * Skill Display Utilities
 *
 * Converts internal skill IDs to human-readable display names.
 * Uses SKILL_CATEGORIES from constants as the single source of truth.
 *
 * @example
 * getSkillDisplayName("fiveComplements.4=5-1") // "+4 = +5 - 1"
 * getCategoryDisplayName("fiveComplements") // "Five Complements (Addition)"
 */
 
import { SKILL_CATEGORIES, type SkillCategoryKey } from '@/constants/skillCategories'
 
/**
 * Get human-readable display name for a full skill ID
 *
 * @param fullSkillId - e.g., "fiveComplements.4=5-1" or "basic.directAddition"
 * @returns Human-readable name, e.g., "+4 = +5 - 1" or "Direct Addition (1-4)"
 *
 * @example
 * getSkillDisplayName("fiveComplements.4=5-1") // "+4 = +5 - 1"
 * getSkillDisplayName("basic.directAddition")  // "Direct Addition (1-4)"
 * getSkillDisplayName("tenComplements.9=10-1") // "+9 = +10 - 1"
 * getSkillDisplayName("unknown.skill")         // "skill" (graceful fallback)
 */
export function getSkillDisplayName(fullSkillId: string): string {
  const dotIndex = fullSkillId.indexOf('.')
  if (dotIndex === -1) return fullSkillId
 
  const category = fullSkillId.slice(0, dotIndex)
  const shortKey = fullSkillId.slice(dotIndex + 1)
 
  const categoryData = SKILL_CATEGORIES[category as SkillCategoryKey]
  if (!categoryData) return shortKey || fullSkillId
 
  const skills = categoryData.skills as Record<string, string>
  return skills[shortKey] || shortKey || fullSkillId
}
 
/**
 * Get category display name from category ID
 *
 * @param categoryId - e.g., "fiveComplements" or "tenComplementsSub"
 * @returns Human-readable category name
 *
 * @example
 * getCategoryDisplayName("fiveComplements")    // "Five Complements (Addition)"
 * getCategoryDisplayName("tenComplementsSub")  // "Ten Complements (Subtraction)"
 * getCategoryDisplayName("basic")              // "Basic Skills"
 * getCategoryDisplayName("unknown")            // "unknown" (graceful fallback)
 */
export function getCategoryDisplayName(categoryId: string): string {
  const categoryData = SKILL_CATEGORIES[categoryId as SkillCategoryKey]
  return categoryData?.name || categoryId
}
 
/**
 * Parse a full skill ID into category and short key
 *
 * @param fullSkillId - e.g., "fiveComplements.4=5-1"
 * @returns Object with category and shortKey
 *
 * @example
 * parseSkillId("fiveComplements.4=5-1") // { category: "fiveComplements", shortKey: "4=5-1" }
 * parseSkillId("noCategory")             // { category: "", shortKey: "noCategory" }
 */
export function parseSkillId(fullSkillId: string): {
  category: string
  shortKey: string
} {
  const dotIndex = fullSkillId.indexOf('.')
  if (dotIndex === -1) {
    return { category: '', shortKey: fullSkillId }
  }
  return {
    category: fullSkillId.slice(0, dotIndex),
    shortKey: fullSkillId.slice(dotIndex + 1),
  }
}
 
/**
 * Check if a category ID is valid
 */
export function isValidCategory(categoryId: string): categoryId is SkillCategoryKey {
  return categoryId in SKILL_CATEGORIES
}
 
/**
 * Get all skill IDs in a category with their display names
 *
 * @param categoryId - e.g., "fiveComplements"
 * @returns Array of { id, displayName } objects, or empty array if invalid category
 */
export function getSkillsInCategory(
  categoryId: string
): Array<{ id: string; displayName: string }> {
  const categoryData = SKILL_CATEGORIES[categoryId as SkillCategoryKey]
  if (!categoryData) return []
 
  const skills = categoryData.skills as Record<string, string>
  return Object.entries(skills).map(([shortKey, displayName]) => ({
    id: `${categoryId}.${shortKey}`,
    displayName,
  }))
}