All files / src/utils colorUtils.ts

80.35% Statements 45/56
81.48% Branches 44/54
90.9% Functions 10/11
83.33% Lines 40/48

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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218                                                  830x               830x                         10x       10x   2x   2x   2x   1x   1x   2x                           105x       105x   2x   1x   2x   1x   1x   98x                     6x                   6x                   62x                 62x                   14x 14x   14x 11x 9x 7x 4x 4x   2x                   6x                     10x 10x 10x 10x     10x     10x                                                         54x 54x          
import { SecurityLevelColorPair } from "../constants/colorConstants";
import { SecurityLevel } from "../types/cia";
 
/**
 * Utility functions for color management in security visualization
 *
 * ## Business Perspective
 *
 * These color utilities ensure consistent visual representation of security levels
 * across the application, helping users quickly recognize security states through
 * color psychology (red for critical issues, green for safe states, etc.). 🎨
 *
 * Consistent color representation is essential for risk communication and
 * establishing intuitive security level recognition patterns for users.
 */
 
/**
 * Get color pair (background and text) for a specific security level
 *
 * @param level - Security level to get color for
 * @returns Object with background and text color
 */
export function getSecurityLevelColorPair(
  level: SecurityLevel
): SecurityLevelColorPair {
  const colorMap: Record<SecurityLevel, SecurityLevelColorPair> = {
    None: { bg: "#f5f5f5", text: "#a0a0a0" },
    Low: { bg: "#e3f2fd", text: "#1976d2" },
    Moderate: { bg: "#e8f5e9", text: "#2e7d32" },
    High: { bg: "#fff8e1", text: "#ff8f00" },
    "Very High": { bg: "#fbe9e7", text: "#d84315" },
  };
 
  return colorMap[level] || colorMap["None"];
}
 
/**
 * Get CSS color class for security level
 * @param level - Security level
 * @returns CSS class string
 */
export function getSecurityLevelColorClass(
  level: SecurityLevel | string
): string {
  // Normalize the level to handle case variations
  const normalizedLevel =
    typeof level === "string"
      ? level.toLowerCase().trim()
      : String(level).toLowerCase().trim();
 
  switch (normalizedLevel) {
    case "none":
      return "text-red-600 dark:text-red-400";
    case "low":
      return "text-yellow-600 dark:text-yellow-400";
    case "moderate":
      return "text-blue-600 dark:text-blue-400";
    case "high":
      return "text-green-600 dark:text-green-400";
    case "very high":
      return "text-purple-600 dark:text-purple-400";
    default:
      return "text-gray-600 dark:text-gray-400";
  }
}
 
/**
 * Get CSS background color class for security level
 * @param level - Security level
 * @returns CSS background class string
 */
export function getSecurityLevelBackgroundClass(
  level: SecurityLevel | string
): string {
  // Normalize the level to handle case variations
  const normalizedLevel =
    typeof level === "string"
      ? level.toLowerCase().trim()
      : String(level).toLowerCase().trim();
 
  switch (normalizedLevel) {
    case "none":
      return "bg-red-100 dark:bg-red-900 dark:bg-opacity-20";
    case "low":
      return "bg-yellow-100 dark:bg-yellow-900 dark:bg-opacity-20";
    case "moderate":
      return "bg-blue-100 dark:bg-blue-900 dark:bg-opacity-20";
    case "high":
      return "bg-green-100 dark:bg-green-900 dark:bg-opacity-20";
    case "very high":
      return "bg-purple-100 dark:bg-purple-900 dark:bg-opacity-20";
    default:
      return "bg-gray-100 dark:bg-gray-800 dark:bg-opacity-20";
  }
}
 
/**
 * Get security level background color
 *
 * @param level - Security level
 * @returns Background color for the security level
 */
export function getSecurityLevelBackground(level: SecurityLevel): string {
  return getSecurityLevelColorPair(level).bg;
}
 
/**
 * Get security level text color
 *
 * @param level - Security level
 * @returns Text color for the security level
 */
export function getSecurityLevelTextColor(level: SecurityLevel): string {
  return getSecurityLevelColorPair(level).text;
}
 
/**
 * Get color for risk level
 *
 * @param riskLevel - Risk level string
 * @returns Color corresponding to the risk level
 */
export function getRiskLevelColor(riskLevel: string): string {
  const riskColorMap: Record<string, string> = {
    Critical: "#d32f2f", // Dark red
    High: "#f57c00", // Orange
    Medium: "#fbc02d", // Amber
    Low: "#4caf50", // Green
    Minimal: "#2196f3", // Blue
    Unknown: "#9e9e9e", // Gray
  };
 
  return riskColorMap[riskLevel] || riskColorMap["Unknown"];
}
 
/**
 * Get hex color for a security level based on current theme
 *
 * @param level - The security level
 * @returns Hex color code for the given security level
 */
export function getSecurityLevelHexColor(level: string): string {
  const normalizedLevel = level.toLowerCase();
  const isDarkMode = document.documentElement.classList.contains("dark");
 
  if (normalizedLevel === "none") return isDarkMode ? "#ef5350" : "#f44336";
  if (normalizedLevel === "low") return isDarkMode ? "#ffb74d" : "#ff9800";
  if (normalizedLevel === "moderate") return isDarkMode ? "#4fc3f7" : "#2196f3";
  if (normalizedLevel === "high") return isDarkMode ? "#66bb6a" : "#4caf50";
  if (normalizedLevel === "very high")
    return isDarkMode ? "#ab47bc" : "#9c27b0";
 
  return isDarkMode ? "#9e9e9e" : "#757575"; // Default gray for unknown levels
}
 
/**
 * Get CSS class for a security level
 *
 * @param level - Security level
 * @returns CSS class name for styling
 */
export function getSecurityLevelClass(level: SecurityLevel): string {
  return `security-level-${level.toLowerCase().replace(/\s+/g, "-")}`;
}
 
/**
 * Calculate contrast color (black or white) based on background
 *
 * @param backgroundColor - Hex color code
 * @returns Black or white based on contrast
 */
export function getContrastColor(backgroundColor: string): string {
  // Convert hex to RGB
  const hex = backgroundColor.replace("#", "");
  const r = parseInt(hex.substring(0, 2), 16);
  const g = parseInt(hex.substring(2, 4), 16);
  const b = parseInt(hex.substring(4, 6), 16);
 
  // Calculate luminance
  const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
 
  // Return black for light backgrounds, white for dark
  return luminance > 0.5 ? "#000000" : "#ffffff";
}
 
/**
 * Convert hex color to RGB values
 *
 * @param hex - Hex color string (e.g., #RRGGBB)
 * @returns RGB color object
 */
export function hexToRgb(hex: string): { r: number; g: number; b: number } {
  // Ensure hex is properly formatted with leading #
  const cleanHex = hex.charAt(0) === "#" ? hex.substring(1) : hex;
 
  // Use substring instead of deprecated substr
  const r = parseInt(cleanHex.substring(0, 2), 16);
  const g = parseInt(cleanHex.substring(2, 4), 16);
  const b = parseInt(cleanHex.substring(4, 6), 16);
 
  return { r, g, b };
}
 
/**
 * Get background color class for security score (0-100)
 * Preserve the exact behavior from main branch
 *
 * @param score - Security score (0-100)
 * @returns CSS class for the security score background color
 */
export function getSecurityScoreColorClass(score: number): string {
  Iif (score <= 30) return "bg-red-600"; // Critical
  Eif (score <= 50) return "bg-yellow-400"; // Medium
  if (score <= 60) return "bg-orange-500"; // High
  if (score <= 80) return "bg-green-500"; // Low
  return "bg-blue-500"; // Minimal
}