import { ReactNode } from "react"; export const patterns = [ { regex: //g, className: "bg-blue-200 text-blue-800", label: "Personne", }, { regex: //g, className: "bg-green-200 text-green-800", label: "Adresse Email", }, { regex: //g, className: "bg-purple-200 text-purple-800", label: "N° de Téléphone", }, { regex: //g, className: "bg-red-200 text-red-800", label: "Lieu", }, { regex: //g, className: "bg-yellow-200 text-yellow-800", label: "IBAN", }, { regex: //g, className: "bg-indigo-200 text-indigo-800", label: "Organisation", }, { regex: //g, className: "bg-pink-200 text-pink-800", label: "Date", }, { regex: //g, className: "bg-cyan-200 text-cyan-800", label: "Adresse (BE)", }, { regex: //g, className: "bg-violet-200 text-violet-800", label: "N° de Tél. (BE)", }, { regex: //g, className: "bg-orange-200 text-orange-800", label: "Carte de Crédit", }, { regex: //g, className: "bg-teal-200 text-teal-800", label: "URL", }, { regex: //g, className: "bg-gray-300 text-gray-900", label: "Adresse IP", }, { regex: //g, className: "bg-pink-300 text-pink-900", label: "Date & Heure", }, { regex: //g, className: "bg-red-300 text-red-900", label: "N° Registre National", }, { regex: //g, className: "bg-yellow-300 text-yellow-900", label: "TVA (BE)", }, { regex: //g, className: "bg-lime-200 text-lime-800", label: "N° d'entreprise (BE)", }, { regex: //g, className: "bg-emerald-200 text-emerald-800", label: "ID Pro (BE)", }, ]; interface EntityMapping { originalValue: string; anonymizedValue: string; entityType: string; startIndex: number; endIndex: number; } export const highlightEntities = ( text: string, entityMappings?: EntityMapping[] ): ReactNode => { if (!text) return text; const replacements: Array<{ start: number; end: number; element: ReactNode; }> = []; // Si on a des mappings, on les utilise pour créer un mapping des valeurs anonymisées const anonymizedValueMap = new Map< string, { label: string; className: string } >(); if (entityMappings) { entityMappings.forEach((mapping) => { // Trouver le pattern correspondant au type d'entité const pattern = patterns.find((p) => p.label === mapping.entityType); if (pattern) { anonymizedValueMap.set(mapping.anonymizedValue, { label: mapping.anonymizedValue, className: pattern.className, }); } }); } // Trouver toutes les correspondances patterns.forEach((pattern, patternIndex) => { const regex = new RegExp(pattern.regex.source, pattern.regex.flags); let match; while ((match = regex.exec(text)) !== null) { const start = match.index; const end = match.index + match[0].length; // Vérifier qu'il n'y a pas de chevauchement avec des remplacements existants const hasOverlap = replacements.some( (r) => (start >= r.start && start < r.end) || (end > r.start && end <= r.end) ); if (!hasOverlap) { // Chercher si on a un mapping pour cette entité let displayLabel = pattern.label; const displayClass = pattern.className; // Changé de 'let' à 'const' if (entityMappings) { // Compter les occurrences précédentes du même type pour déterminer le numéro const entityType = pattern.label; const previousMatches = replacements.filter((r) => { // Correction du type 'any' en utilisant une interface plus spécifique const element = r.element as React.ReactElement<{ className?: string; }>; const prevPattern = patterns.find( (p) => p.className === element?.props?.className?.split(" ")[0] + " " + element?.props?.className?.split(" ")[1] ); return prevPattern?.label === entityType; }).length; const matchingMapping = entityMappings.find( (mapping) => mapping.entityType === entityType ); if (matchingMapping) { // Utiliser le compteur pour déterminer le bon numéro avec des crochets const entityCount = previousMatches + 1; displayLabel = `${entityType} [${entityCount}]`; } } const element = ( {displayLabel} ); replacements.push({ start, end, element }); } } }); // Trier les remplacements par position replacements.sort((a, b) => a.start - b.start); // Construire le résultat final if (replacements.length === 0) { return text; } const parts: ReactNode[] = []; let lastIndex = 0; replacements.forEach((replacement) => { // Ajouter le texte avant le remplacement if (replacement.start > lastIndex) { parts.push(text.slice(lastIndex, replacement.start)); } // Ajouter l'élément de remplacement parts.push(replacement.element); lastIndex = replacement.end; }); // Ajouter le texte restant if (lastIndex < text.length) { parts.push(text.slice(lastIndex)); } return parts; };