mac multi select
This commit is contained in:
@@ -175,8 +175,8 @@ export async function POST(req: NextRequest) {
|
|||||||
|
|
||||||
// ✅ Définir l'URL AVANT de l'utiliser
|
// ✅ Définir l'URL AVANT de l'utiliser
|
||||||
const presidioAnalyzerUrl =
|
const presidioAnalyzerUrl =
|
||||||
"http://analyzer.151.80.20.211.sslip.io/analyze";
|
// "http://analyzer.151.80.20.211.sslip.io/analyze";
|
||||||
|
"http://localhost:5001/analyze";
|
||||||
try {
|
try {
|
||||||
const analyzeResponse = await fetch(presidioAnalyzerUrl, {
|
const analyzeResponse = await fetch(presidioAnalyzerUrl, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -213,7 +213,8 @@ export async function POST(req: NextRequest) {
|
|||||||
|
|
||||||
console.log("🔍 Appel à Presidio Anonymizer...");
|
console.log("🔍 Appel à Presidio Anonymizer...");
|
||||||
const presidioAnonymizerUrl =
|
const presidioAnonymizerUrl =
|
||||||
"http://analyzer.151.80.20.211.sslip.io/anonymize";
|
// "http://analyzer.151.80.20.211.sslip.io/anonymize";
|
||||||
|
"http://localhost:5001/anonymize";
|
||||||
|
|
||||||
const anonymizeResponse = await fetch(presidioAnonymizerUrl, {
|
const anonymizeResponse = await fetch(presidioAnonymizerUrl, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -254,26 +255,39 @@ export async function POST(req: NextRequest) {
|
|||||||
|
|
||||||
// Extraire tous les remplacements [XXX] du texte anonymisé
|
// Extraire tous les remplacements [XXX] du texte anonymisé
|
||||||
const replacementPattern = /\[[^\]]+\]/g;
|
const replacementPattern = /\[[^\]]+\]/g;
|
||||||
const foundReplacements = anonymizedText.match(replacementPattern) || [];
|
const foundReplacements =
|
||||||
|
anonymizedText.match(replacementPattern) || [];
|
||||||
|
|
||||||
console.log("🔍 Remplacements trouvés dans le texte anonymisé:", foundReplacements);
|
console.log(
|
||||||
|
"🔍 Remplacements trouvés dans le texte anonymisé:",
|
||||||
|
foundReplacements
|
||||||
|
);
|
||||||
|
|
||||||
// Trier les entités par position
|
// Trier les entités par position
|
||||||
const sortedResults = [...analyzerResults].sort((a, b) => a.start - b.start);
|
const sortedResults = [...analyzerResults].sort(
|
||||||
|
(a, b) => a.start - b.start
|
||||||
|
);
|
||||||
|
|
||||||
// Associer chaque entité avec son remplacement correspondant
|
// Associer chaque entité avec son remplacement correspondant
|
||||||
sortedResults.forEach((result, index) => {
|
sortedResults.forEach((result, index) => {
|
||||||
const originalValue = originalText.substring(result.start, result.end);
|
const originalValue = originalText.substring(
|
||||||
|
result.start,
|
||||||
|
result.end
|
||||||
|
);
|
||||||
|
|
||||||
if (index < foundReplacements.length) {
|
if (index < foundReplacements.length) {
|
||||||
// Utiliser le remplacement correspondant par ordre d'apparition
|
// Utiliser le remplacement correspondant par ordre d'apparition
|
||||||
replacementMap[originalValue] = foundReplacements[index];
|
replacementMap[originalValue] = foundReplacements[index];
|
||||||
console.log(`✅ Mapping ordonné: "${originalValue}" -> "${foundReplacements[index]}"`);
|
console.log(
|
||||||
|
`✅ Mapping ordonné: "${originalValue}" -> "${foundReplacements[index]}"`
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// Fallback si pas assez de remplacements trouvés
|
// Fallback si pas assez de remplacements trouvés
|
||||||
const fallbackValue = `[${result.entity_type.toUpperCase()}]`;
|
const fallbackValue = `[${result.entity_type.toUpperCase()}]`;
|
||||||
replacementMap[originalValue] = fallbackValue;
|
replacementMap[originalValue] = fallbackValue;
|
||||||
console.log(`⚠️ Fallback: "${originalValue}" -> "${fallbackValue}"`);
|
console.log(
|
||||||
|
`⚠️ Fallback: "${originalValue}" -> "${fallbackValue}"`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ export const InstructionsPanel: React.FC = () => {
|
|||||||
<ul className="space-y-1 text-blue-700">
|
<ul className="space-y-1 text-blue-700">
|
||||||
<li>• Survolez les mots pour les mettre en évidence</li>
|
<li>• Survolez les mots pour les mettre en évidence</li>
|
||||||
<li>
|
<li>
|
||||||
• Cliquez pour sélectionner un mot, Crtl + clic pour plusieurs
|
• Cliquez pour sélectionner un mot, Ctrl/CMD (ou Shift) + clic.
|
||||||
mots
|
|
||||||
</li>
|
</li>
|
||||||
<li>• Faites clic droit pour ouvrir le menu contextuel</li>
|
<li>• Faites clic droit pour ouvrir le menu contextuel</li>
|
||||||
<li>• Modifiez les labels et couleurs selon vos besoins</li>
|
<li>• Modifiez les labels et couleurs selon vos besoins</li>
|
||||||
|
|||||||
@@ -53,7 +53,10 @@ export const InteractiveTextEditor: React.FC<InteractiveTextEditorProps> = ({
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
if (event.ctrlKey || event.metaKey) {
|
// Support multi-sélection avec Ctrl, Cmd et Shift
|
||||||
|
const isMultiSelect = event.ctrlKey || event.metaKey || event.shiftKey;
|
||||||
|
|
||||||
|
if (isMultiSelect) {
|
||||||
setSelectedWords((prev) => {
|
setSelectedWords((prev) => {
|
||||||
const newSet = new Set(prev);
|
const newSet = new Set(prev);
|
||||||
if (newSet.has(index)) {
|
if (newSet.has(index)) {
|
||||||
|
|||||||
@@ -70,11 +70,24 @@ export const TextDisplay: React.FC<TextDisplayProps> = ({
|
|||||||
className={className}
|
className={className}
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
|
userSelect: "none",
|
||||||
|
WebkitUserSelect: "none",
|
||||||
}}
|
}}
|
||||||
onMouseEnter={() => onWordHover(index)}
|
onMouseEnter={() => onWordHover(index)}
|
||||||
onMouseLeave={() => onWordHover(null)}
|
onMouseLeave={() => onWordHover(null)}
|
||||||
onClick={(e) => onWordClick(index, e)}
|
onClick={(e) => {
|
||||||
|
if (e.metaKey || e.ctrlKey || e.shiftKey) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
|
onWordClick(index, e);
|
||||||
|
}}
|
||||||
onContextMenu={onContextMenu}
|
onContextMenu={onContextMenu}
|
||||||
|
onMouseDown={(e) => {
|
||||||
|
if (e.metaKey || e.ctrlKey || e.shiftKey) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}}
|
||||||
title={
|
title={
|
||||||
word.isEntity
|
word.isEntity
|
||||||
? `Entité: ${word.entityType} (Original: ${word.text})`
|
? `Entité: ${word.entityType} (Original: ${word.text})`
|
||||||
|
|||||||
@@ -162,11 +162,15 @@ export const useContextMenu = ({
|
|||||||
if (!contextMenu.selectedText) return;
|
if (!contextMenu.selectedText) return;
|
||||||
|
|
||||||
const originalText = contextMenu.selectedText;
|
const originalText = contextMenu.selectedText;
|
||||||
const firstWordIndex = contextMenu.wordIndices[0];
|
const selectedIndices = contextMenu.wordIndices;
|
||||||
|
|
||||||
const clickedWord = words[firstWordIndex];
|
// Calculer les positions de début et fin pour tous les mots sélectionnés
|
||||||
const wordStart = clickedWord?.start;
|
const sortedIndices = selectedIndices.sort((a, b) => a - b);
|
||||||
const wordEnd = clickedWord?.end;
|
const firstWord = words[sortedIndices[0]];
|
||||||
|
const lastWord = words[sortedIndices[sortedIndices.length - 1]];
|
||||||
|
|
||||||
|
const wordStart = firstWord?.start;
|
||||||
|
const wordEnd = lastWord?.end;
|
||||||
|
|
||||||
const existingMapping = entityMappings.find(
|
const existingMapping = entityMappings.find(
|
||||||
(m) => m.text === originalText
|
(m) => m.text === originalText
|
||||||
@@ -179,7 +183,9 @@ export const useContextMenu = ({
|
|||||||
text: originalText,
|
text: originalText,
|
||||||
label: displayName,
|
label: displayName,
|
||||||
entityType,
|
entityType,
|
||||||
applyToAll
|
applyToAll,
|
||||||
|
wordIndices: selectedIndices,
|
||||||
|
positions: { start: wordStart, end: wordEnd }
|
||||||
});
|
});
|
||||||
|
|
||||||
onUpdateMapping(
|
onUpdateMapping(
|
||||||
|
|||||||
Reference in New Issue
Block a user