import React, { useState, useRef, useEffect } from "react"; import { Trash2, Check, RotateCcw } from "lucide-react"; import { COLOR_PALETTE, type ColorOption } from "../config/colorPalette"; // import { EntityMapping } from "../config/entityLabels"; // SUPPRIMER cette ligne interface ContextMenuProps { contextMenu: { visible: boolean; x: number; y: number; selectedText: string; wordIndices: number[]; }; existingLabels: string[]; // entityMappings: EntityMapping[]; // SUPPRIMER cette ligne onApplyLabel: ( displayName: string, applyToAll?: boolean ) => void; onApplyColor: ( color: string, colorName: string, applyToAll?: boolean ) => void; onRemoveLabel: (applyToAll?: boolean) => void; getCurrentColor: (selectedText: string) => string; } const colorOptions: ColorOption[] = COLOR_PALETTE; export const ContextMenu: React.FC = ({ contextMenu, existingLabels, // entityMappings, // SUPPRIMER cette ligne onApplyLabel, onApplyColor, onRemoveLabel, getCurrentColor, }) => { const [customLabel, setCustomLabel] = useState(""); const [showNewLabelInput, setShowNewLabelInput] = useState(false); const [showColorPalette, setShowColorPalette] = useState(false); const [applyToAll, setApplyToAll] = useState(false); const menuRef = useRef(null); const inputRef = useRef(null); // Fonction corrigée pour le bouton + const handleNewLabelClick = (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); console.log("Bouton + cliqué - Ouverture du champ de saisie"); setShowNewLabelInput(true); setShowColorPalette(false); }; const handleApplyCustomLabel = (e?: React.MouseEvent) => { if (e) { e.preventDefault(); e.stopPropagation(); } if (customLabel.trim()) { console.log( "Application du label personnalisé:", customLabel.trim(), "À toutes les occurrences:", applyToAll ); onApplyLabel(customLabel.trim(), applyToAll); // CORRIGER: 2 paramètres seulement setCustomLabel(""); setShowNewLabelInput(false); } }; // Modifier la fonction handleCancelNewLabel pour accepter les deux types d'événements const handleCancelNewLabel = (e: React.MouseEvent | React.KeyboardEvent) => { e.preventDefault(); e.stopPropagation(); console.log("Annulation du nouveau label"); setShowNewLabelInput(false); setCustomLabel(""); }; // Fonction pour empêcher la propagation des événements const handleMenuClick = (e: React.MouseEvent) => { e.stopPropagation(); }; // Auto-focus sur l'input quand il apparaît useEffect(() => { if (showNewLabelInput && inputRef.current) { setTimeout(() => { inputRef.current?.focus(); }, 0); } }, [showNewLabelInput]); if (!contextMenu.visible) return null; // Calcul du positionnement pour s'assurer que le menu reste visible const calculatePosition = () => { const menuWidth = Math.max(600, contextMenu.selectedText.length * 8 + 400); // Largeur dynamique basée sur le texte const menuHeight = 60; // Hauteur fixe pour une seule ligne const padding = 10; let x = contextMenu.x; let y = contextMenu.y; // Ajuster X pour rester dans la fenêtre if (x + menuWidth / 2 > window.innerWidth - padding) { x = window.innerWidth - menuWidth / 2 - padding; } if (x - menuWidth / 2 < padding) { x = menuWidth / 2 + padding; } // Ajuster Y pour rester dans la fenêtre if (y + menuHeight > window.innerHeight - padding) { y = contextMenu.y - menuHeight - 20; // Afficher au-dessus } return { x, y }; }; const position = calculatePosition(); return (
e.stopPropagation()} > {/* Une seule ligne avec tous les contrôles */}
{/* Texte sélectionné complet */}
{contextMenu.selectedText}
{/* Labels existants */} {existingLabels.length > 0 && ( <>
)} {/* Nouveau label */}
{!showNewLabelInput ? ( ) : (
{ e.stopPropagation(); setCustomLabel(e.target.value); }} onKeyDown={(e) => { e.stopPropagation(); if (e.key === "Enter") { e.preventDefault(); handleApplyCustomLabel(); } else if (e.key === "Escape") { e.preventDefault(); handleCancelNewLabel(e); } }} onClick={(e) => e.stopPropagation()} onMouseDown={(e) => e.stopPropagation()} onFocus={(e) => e.stopPropagation()} className="text-xs border border-gray-300 rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-blue-500 w-20" placeholder="Label" />
)}
{/* Sélecteur de couleur */}
)}
{/* Bouton supprimer */}
{/* Case à cocher "Toutes les occurrences" */}
{ e.stopPropagation(); setApplyToAll(e.target.checked); console.log( "Appliquer à toutes les occurrences:", e.target.checked ); }} onClick={(e) => e.stopPropagation()} onMouseDown={(e) => e.stopPropagation()} className="h-3 w-3 text-blue-600 focus:ring-blue-500 border-gray-300 rounded" />
); };