v1.0 - Version stable: multi-PC, détection UI-DETR-1, 3 modes exécution

- Frontend v4 accessible sur réseau local (192.168.1.40)
- Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard)
- Ollama GPU fonctionnel
- Self-healing interactif
- Dashboard confiance

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Dom
2026-01-29 11:23:51 +01:00
parent 21bfa3b337
commit a27b74cf22
1595 changed files with 412691 additions and 400 deletions

275
i18n/README.md Normal file
View File

@@ -0,0 +1,275 @@
# Système de Localisation - RPA Vision V3
> **Support multilingue pour l'interface utilisateur**
> Auteur : Dom, Alice, Kiro - 7 janvier 2026
## 🌍 Langues Supportées
| Langue | Code | Statut | Fichier |
|--------|------|--------|---------|
| 🇫🇷 Français | `fr` | ✅ Complet | `fr.json` |
| 🇺🇸 English | `en` | ✅ Complet | `en.json` |
| 🇪🇸 Español | `es` | ✅ Complet | `es.json` |
| 🇩🇪 Deutsch | `de` | ✅ Complet | `de.json` |
## 📁 Structure des Fichiers
```
i18n/
├── config.json # Configuration des langues
├── fr.json # Traductions françaises (référence)
├── en.json # Traductions anglaises
├── es.json # Traductions espagnoles
├── de.json # Traductions allemandes
├── validate_translations.py # Script de validation
└── README.md # Ce fichier
```
## 🚀 Utilisation Rapide
### Dans un Composant React
```typescript
import { useLocalization } from '../services/LocalizationService';
const MonComposant = () => {
const { t, changeLanguage } = useLocalization();
return (
<div>
<h1>{t('realDemo.title')}</h1>
<button onClick={() => changeLanguage('en')}>
Switch to English
</button>
</div>
);
};
```
### Clés de Traduction Principales
```typescript
// Démonstration réelle
t('realDemo.title') // "Démonstration Réelle"
t('realDemo.status.connected') // "Connecté"
t('realDemo.controls.createWorkflow') // "Créer Workflow de Démo"
// Interface commune
t('common.loading') // "Chargement..."
t('common.save') // "Sauvegarder"
t('common.cancel') // "Annuler"
// Temps et unités
t('time.seconds') // "secondes"
t('units.pixels') // "pixels"
```
## 🔧 Validation
### Script de Validation Automatique
```bash
# Valider toutes les traductions
python validate_translations.py
# Exemple de sortie
✅ Chargé: fr.json
✅ Chargé: en.json
✅ Chargé: es.json
✅ Chargé: de.json
📋 Clés de référence (fr): 127
🔍 en: 127 clés (0 manquantes, 0 supplémentaires)
🔍 es: 127 clés (0 manquantes, 0 supplémentaires)
🔍 de: 127 clés (0 manquantes, 0 supplémentaires)
✅ VALIDATION RÉUSSIE: Aucun problème détecté!
```
### Validation Manuelle
```bash
# Vérifier la syntaxe JSON
python -m json.tool fr.json > /dev/null && echo "✅ fr.json valide"
# Compter les clés
jq 'paths(scalars) | length' fr.json
# Comparer les structures
diff <(jq -r 'paths(scalars) as $p | $p | join(".")' fr.json | sort) \
<(jq -r 'paths(scalars) as $p | $p | join(".")' en.json | sort)
```
## 📝 Conventions
### Nommage des Clés
- **Modules** : `realDemo`, `dashboard`, `workflow`
- **Catégories** : `status`, `messages`, `actions`, `controls`
- **Format** : `camelCase` pour la cohérence
- **Hiérarchie** : Maximum 3 niveaux de profondeur
### Format des Valeurs
```json
{
"simple": "Texte simple",
"withParams": "Bonjour {{name}}, vous avez {{count}} messages",
"multiline": "Première ligne\nSeconde ligne",
"withHtml": "Texte avec <strong>mise en forme</strong>"
}
```
### Paramètres Dynamiques
```typescript
// Utilisation des paramètres
t('messages.welcome', { name: 'Alice', count: 5 })
// Résultat: "Bienvenue Alice, vous avez 5 messages"
```
## 🌐 Configuration des Locales
### Formats par Langue
| Langue | Date | Heure | Devise | Décimal | Milliers |
|--------|------|-------|--------|---------|----------|
| 🇫🇷 fr | DD/MM/YYYY | HH:mm | EUR (€) | , | espace |
| 🇺🇸 en | MM/DD/YYYY | h:mm A | USD ($) | . | , |
| 🇪🇸 es | DD/MM/YYYY | HH:mm | EUR (€) | , | . |
| 🇩🇪 de | DD.MM.YYYY | HH:mm | EUR (€) | , | . |
### Exemples de Formatage
```typescript
// Date: 7 janvier 2026
formatDate(date)
// fr: "07/01/2026"
// en: "01/07/2026"
// de: "07.01.2026"
// Nombre: 1234.56
formatNumber(1234.56)
// fr: "1 234,56"
// en: "1,234.56"
// de: "1.234,56"
// Devise: 99.99
formatCurrency(99.99)
// fr: "99,99 €"
// en: "$99.99"
// de: "99,99 €"
```
## 🔄 Ajout d'une Nouvelle Langue
### 1. Configuration
```json
// Ajouter dans config.json
{
"code": "it",
"name": "Italiano",
"flag": "🇮🇹",
"dateFormat": "DD/MM/YYYY",
"timeFormat": "HH:mm",
"currency": "EUR",
"currencySymbol": "€",
"decimalSeparator": ",",
"thousandsSeparator": "."
}
```
### 2. Fichier de Traduction
```bash
# Copier la structure française
cp fr.json it.json
# Traduire le contenu en gardant la structure JSON
# Respecter les placeholders {{param}}
```
### 3. Validation
```bash
# Valider la nouvelle langue
python validate_translations.py
# Vérifier l'intégration
# Tester dans l'interface utilisateur
```
## 🎯 Bonnes Pratiques
### Pour les Traducteurs
1. **Contexte** : Comprendre le contexte d'utilisation
2. **Cohérence** : Utiliser les mêmes termes pour les mêmes concepts
3. **Longueur** : Adapter la longueur selon l'espace disponible
4. **Culture** : Respecter les conventions culturelles
### Pour les Développeurs
1. **Clés descriptives** : Utiliser des noms de clés explicites
2. **Paramètres** : Préférer les paramètres aux concaténations
3. **Pluralisation** : Gérer les formes plurielles si nécessaire
4. **Fallback** : Toujours prévoir une langue de secours
## 🐛 Dépannage
### Problèmes Courants
#### Traduction Non Affichée
```typescript
// Vérifier la clé
console.log(t('ma.cle.inexistante')); // Affiche la clé si non trouvée
// Vérifier la langue actuelle
console.log(getCurrentLanguage());
// Vérifier le chargement
console.log(localizationService.translations);
```
#### Fichier JSON Invalide
```bash
# Valider la syntaxe
python -m json.tool problematic.json
# Erreurs communes:
# - Virgule en trop
# - Guillemets manquants
# - Caractères d'échappement incorrects
```
#### Clés Manquantes
```bash
# Identifier les clés manquantes
python validate_translations.py
# Comparer avec la référence
diff fr.json en.json
```
## 📊 Statistiques Actuelles
- **Total des clés** : 156 traductions (+3 nouvelles clés pour RealDemo)
- **Couverture** : 100% pour toutes les langues
- **Modules couverts** :
- Démonstration réelle (`realDemo`) - **ÉTENDU**
- Interface commune (`common`)
- Temps et unités (`time`, `units`)
## 🔮 Évolutions Prévues
- **Pluralisation** : Gestion des formes plurielles
- **Contexte dynamique** : Traductions selon le contexte
- **Traduction automatique** : Assistance IA pour nouvelles langues
- **Validation continue** : Intégration dans le CI/CD
---
**🌍 Le système de localisation RPA Vision V3 assure une expérience utilisateur internationale de qualité !**

52
i18n/config.json Normal file
View File

@@ -0,0 +1,52 @@
{
"defaultLanguage": "fr",
"supportedLanguages": [
{
"code": "fr",
"name": "Français",
"flag": "🇫🇷",
"dateFormat": "DD/MM/YYYY",
"timeFormat": "HH:mm",
"currency": "EUR",
"currencySymbol": "€",
"decimalSeparator": ",",
"thousandsSeparator": " "
},
{
"code": "en",
"name": "English",
"flag": "🇺🇸",
"dateFormat": "MM/DD/YYYY",
"timeFormat": "h:mm A",
"currency": "USD",
"currencySymbol": "$",
"decimalSeparator": ".",
"thousandsSeparator": ","
},
{
"code": "es",
"name": "Español",
"flag": "🇪🇸",
"dateFormat": "DD/MM/YYYY",
"timeFormat": "HH:mm",
"currency": "EUR",
"currencySymbol": "€",
"decimalSeparator": ",",
"thousandsSeparator": "."
},
{
"code": "de",
"name": "Deutsch",
"flag": "🇩🇪",
"dateFormat": "DD.MM.YYYY",
"timeFormat": "HH:mm",
"currency": "EUR",
"currencySymbol": "€",
"decimalSeparator": ",",
"thousandsSeparator": "."
}
],
"fallbackLanguage": "fr",
"autoDetect": true,
"persistLanguageChoice": true
}

206
i18n/de.json Normal file
View File

@@ -0,0 +1,206 @@
{
"realDemo": {
"title": "Echte Demonstration",
"subtitle": "Schnittstelle für echte Demonstrationen mit dem RPA Vision V3 System",
"component": {
"title": "Echte Demonstration - RPA Vision V3",
"description": "Diese Komponente ermöglicht es, das RPA-System in Echtzeit zu testen.",
"startButton": "Demonstration Starten"
},
"status": {
"connected": "Verbunden",
"disconnected": "Getrennt",
"live": "Live",
"loading": "Lädt...",
"ready": "Bereit",
"error": "Fehler"
},
"connection": {
"notAvailable": "Der echte Demonstrationsserver ist nicht verfügbar.",
"ensureRunning": "Stellen Sie sicher, dass das Skript `demo_real_functionality.py` läuft.",
"checkConnection": "Verbindung Prüfen",
"testApi": "API Testen",
"established": "Verbindung zum echten Demonstrationsserver hergestellt",
"unavailable": "Demonstrationsserver nicht verfügbar",
"impossible": "Verbindung zum Demonstrationsserver nicht möglich"
},
"screen": {
"title": "Echtzeit-Bildschirmaufnahme",
"refresh": "Aktualisieren",
"loading": "Bildschirm wird geladen...",
"noCapture": "Keine Aufnahme verfügbar"
},
"elements": {
"detected": "Erkannte Elemente",
"noText": "Kein Text",
"details": "Element-Details",
"type": "Typ",
"text": "Text",
"position": "Position",
"confidence": "Vertrauen",
"none": "Keine"
},
"controls": {
"title": "Demonstrations-Steuerung",
"createWorkflow": "Demo-Workflow Erstellen",
"executeWorkflow": "Workflow Ausführen",
"executing": "Wird ausgeführt...",
"quickActions": "Schnelle Aktionen",
"testClick": "Test-Klick (200, 200)",
"clickHere": "Hier Klicken"
},
"execution": {
"results": "Ausführungsergebnisse",
"action": "Aktion",
"target": "Ziel",
"success": "Erfolg",
"failure": "Fehler",
"click": "Klick",
"workflow": "Workflow",
"executed": "ausgeführt",
"steps": "Schritte",
"workflowSuccess": "Workflow erfolgreich ausgeführt",
"workflowFailure": "Workflow-Ausführung fehlgeschlagen"
},
"workflow": {
"demo": {
"name": "Einfache Demonstration",
"step1": "1 Sekunde warten",
"step2": "Klick bei (100, 100)",
"step3": "2 Sekunden warten"
}
},
"actions": {
"cancel": "Abbrechen",
"execute": "Ausführen",
"close": "Schließen",
"save": "Speichern"
},
"messages": {
"actionExecuted": "Aktion ausgeführt",
"actionFailed": "Aktion fehlgeschlagen",
"workflowStarted": "Workflow-Ausführung gestartet",
"workflowCompleted": "Workflow erfolgreich ausgeführt",
"workflowFailed": "Workflow-Ausführung fehlgeschlagen",
"noConnection": "Keine Verbindung zum Demonstrationsserver",
"executionError": "Ausführungsfehler",
"captureStarted": "Echtzeit-Bildschirmaufnahme gestartet",
"captureStopped": "Echtzeit-Bildschirmaufnahme gestoppt"
}
},
"realDemoTab": {
"title": "Echte Demonstration",
"tabs": {
"demo": "Demonstration",
"config": "Konfiguration",
"help": "Hilfe"
},
"serverUnavailable": {
"title": "Demonstrationsserver Nicht Verfügbar",
"description": "Der echte Demonstrationsserver läuft nicht. Um diese Funktion zu nutzen, müssen Sie den Demonstrationsserver starten.",
"howToStart": "So starten Sie die Demonstration:",
"option1": "Option 1 - Automatisches Skript:",
"option2": "Option 2 - Manueller Start:",
"terminal1": "Terminal 1 - Backend",
"terminal2": "Terminal 2 - Demonstrationsserver",
"terminal3": "Terminal 3 - Frontend",
"checkAgain": "Erneut Prüfen"
},
"config": {
"title": "Demonstrations-Konfiguration",
"servicesStatus": "Service-Status",
"backendFlask": "Flask Backend (5002)",
"demoServer": "Demo Server (5003)",
"frontendReact": "React Frontend (3000)",
"captureSettings": "Aufnahme-Einstellungen",
"captureFrequency": "Aufnahmefrequenz: 1 Sekunde",
"autoDetection": "Automatische UI-Element-Erkennung",
"dataSaving": "Aufnahmen werden in data/demo/ gespeichert",
"security": "Sicherheit",
"securityWarning": "Die echte Demonstration kann Aktionen auf Ihrem System ausführen. Verwenden Sie sie nur in einer sicheren Testumgebung."
},
"help": {
"title": "Leitfaden für Echte Demonstration",
"objective": {
"title": "Ziel",
"description": "Die echte Demonstration ermöglicht es, das RPA Vision V3 System mit echten Interaktionen auf Ihrem Bildschirm zu testen. Sie können die Echtzeit-Elementerkennung sehen und automatisierte Aktionen ausführen."
},
"features": {
"title": "Funktionen",
"realTimeCapture": "Echtzeit-Aufnahme: Ihr Bildschirm wird jede Sekunde aufgenommen",
"uiDetection": "UI-Erkennung: Interaktive Elemente werden automatisch erkannt",
"actionExecution": "Aktionsausführung: Klicken Sie auf erkannte Elemente, um sie zu testen",
"demoWorkflows": "Demo-Workflows: Erstellen und führen Sie Aktionssequenzen aus",
"history": "Verlauf: Verfolgen Sie Ihre Testergebnisse"
},
"precautions": {
"title": "Vorsichtsmaßnahmen",
"testEnvironment": "Nur in einer Testumgebung verwenden",
"realActions": "Aktionen werden tatsächlich auf Ihrem System ausgeführt",
"closeApps": "Schließen Sie wichtige Anwendungen vor dem Testen",
"backupData": "Sichern Sie Ihre wichtigen Daten"
},
"quickStart": {
"title": "Schnellstart",
"step1": "Führen Sie das Skript aus: python start_real_demo.py",
"step2": "Warten Sie, bis alle Services gestartet sind",
"step3": "Öffnen Sie den \"Demonstration\" Tab",
"step4": "Klicken Sie auf \"Demo-Workflow Erstellen\"",
"step5": "Testen Sie die verfügbaren Funktionen"
}
}
},
"common": {
"loading": "Lädt...",
"error": "Fehler",
"success": "Erfolg",
"warning": "Warnung",
"info": "Information",
"ok": "OK",
"cancel": "Abbrechen",
"save": "Speichern",
"delete": "Löschen",
"edit": "Bearbeiten",
"create": "Erstellen",
"update": "Aktualisieren",
"refresh": "Aktualisieren",
"close": "Schließen",
"open": "Öffnen",
"yes": "Ja",
"no": "Nein",
"enabled": "Aktiviert",
"disabled": "Deaktiviert",
"active": "Aktiv",
"inactive": "Inaktiv",
"online": "Online",
"offline": "Offline",
"connected": "Verbunden",
"disconnected": "Getrennt",
"language": "Sprache",
"current": "Aktuell"
},
"time": {
"second": "Sekunde",
"seconds": "Sekunden",
"minute": "Minute",
"minutes": "Minuten",
"hour": "Stunde",
"hours": "Stunden",
"day": "Tag",
"days": "Tage",
"ago": "vor",
"now": "jetzt",
"today": "heute",
"yesterday": "gestern",
"tomorrow": "morgen"
},
"units": {
"pixels": "Pixel",
"percent": "Prozent",
"milliseconds": "Millisekunden",
"seconds": "Sekunden",
"bytes": "Bytes",
"kilobytes": "Kilobytes",
"megabytes": "Megabytes"
}
}

206
i18n/en.json Normal file
View File

@@ -0,0 +1,206 @@
{
"realDemo": {
"title": "Real Demonstration",
"subtitle": "Interface for real demonstrations with the RPA Vision V3 system",
"component": {
"title": "Real Demonstration - RPA Vision V3",
"description": "This component will allow testing the RPA system in real time.",
"startButton": "Start Demonstration"
},
"status": {
"connected": "Connected",
"disconnected": "Disconnected",
"live": "Live",
"loading": "Loading...",
"ready": "Ready",
"error": "Error"
},
"connection": {
"notAvailable": "The real demonstration server is not available.",
"ensureRunning": "Make sure the `demo_real_functionality.py` script is running.",
"checkConnection": "Check Connection",
"testApi": "Test API",
"established": "Connection to real demonstration server established",
"unavailable": "Demonstration server unavailable",
"impossible": "Unable to connect to demonstration server"
},
"screen": {
"title": "Real-Time Screen Capture",
"refresh": "Refresh",
"loading": "Loading screen...",
"noCapture": "No capture available"
},
"elements": {
"detected": "Detected Elements",
"noText": "No text",
"details": "Element Details",
"type": "Type",
"text": "Text",
"position": "Position",
"confidence": "Confidence",
"none": "None"
},
"controls": {
"title": "Demonstration Controls",
"createWorkflow": "Create Demo Workflow",
"executeWorkflow": "Execute Workflow",
"executing": "Executing...",
"quickActions": "Quick Actions",
"testClick": "Test Click (200, 200)",
"clickHere": "Click Here"
},
"execution": {
"results": "Execution Results",
"action": "Action",
"target": "Target",
"success": "Success",
"failure": "Failure",
"click": "Click",
"workflow": "Workflow",
"executed": "executed",
"steps": "steps",
"workflowSuccess": "Workflow executed successfully",
"workflowFailure": "Workflow execution failed"
},
"workflow": {
"demo": {
"name": "Simple Demonstration",
"step1": "Wait 1 second",
"step2": "Click at (100, 100)",
"step3": "Wait 2 seconds"
}
},
"actions": {
"cancel": "Cancel",
"execute": "Execute",
"close": "Close",
"save": "Save"
},
"messages": {
"actionExecuted": "Action executed",
"actionFailed": "Action failed",
"workflowStarted": "Starting workflow execution",
"workflowCompleted": "Workflow executed successfully",
"workflowFailed": "Workflow execution failed",
"noConnection": "No connection to demonstration server",
"executionError": "Execution error",
"captureStarted": "Real-time screen capture started",
"captureStopped": "Real-time screen capture stopped"
}
},
"realDemoTab": {
"title": "Real Demonstration",
"tabs": {
"demo": "Demonstration",
"config": "Configuration",
"help": "Help"
},
"serverUnavailable": {
"title": "Demonstration Server Unavailable",
"description": "The real demonstration server is not running. To use this feature, you need to start the demonstration server.",
"howToStart": "How to start the demonstration:",
"option1": "Option 1 - Automatic script:",
"option2": "Option 2 - Manual startup:",
"terminal1": "Terminal 1 - Backend",
"terminal2": "Terminal 2 - Demonstration server",
"terminal3": "Terminal 3 - Frontend",
"checkAgain": "Check Again"
},
"config": {
"title": "Demonstration Configuration",
"servicesStatus": "Services Status",
"backendFlask": "Flask Backend (5002)",
"demoServer": "Demo Server (5003)",
"frontendReact": "React Frontend (3000)",
"captureSettings": "Capture Settings",
"captureFrequency": "Capture frequency: 1 second",
"autoDetection": "Automatic UI element detection",
"dataSaving": "Saving captures to data/demo/",
"security": "Security",
"securityWarning": "Real demonstration can execute actions on your system. Use only in a secure test environment."
},
"help": {
"title": "Real Demonstration Usage Guide",
"objective": {
"title": "Objective",
"description": "Real demonstration allows testing the RPA Vision V3 system with real interactions on your screen. You can see real-time element detection and execute automated actions."
},
"features": {
"title": "Features",
"realTimeCapture": "Real-time capture: Your screen is captured every second",
"uiDetection": "UI detection: Interactive elements are automatically detected",
"actionExecution": "Action execution: Click on detected elements to test them",
"demoWorkflows": "Demo workflows: Create and execute action sequences",
"history": "History: Track your test results"
},
"precautions": {
"title": "Precautions",
"testEnvironment": "Use only in a test environment",
"realActions": "Actions are executed for real on your system",
"closeApps": "Close important applications before testing",
"backupData": "Backup your important data"
},
"quickStart": {
"title": "Quick Start",
"step1": "Run the script: python start_real_demo.py",
"step2": "Wait for all services to start",
"step3": "Open the \"Demonstration\" tab",
"step4": "Click \"Create Demo Workflow\"",
"step5": "Test available features"
}
}
},
"common": {
"loading": "Loading...",
"error": "Error",
"success": "Success",
"warning": "Warning",
"info": "Information",
"ok": "OK",
"cancel": "Cancel",
"save": "Save",
"delete": "Delete",
"edit": "Edit",
"create": "Create",
"update": "Update",
"refresh": "Refresh",
"close": "Close",
"open": "Open",
"yes": "Yes",
"no": "No",
"enabled": "Enabled",
"disabled": "Disabled",
"active": "Active",
"inactive": "Inactive",
"online": "Online",
"offline": "Offline",
"connected": "Connected",
"disconnected": "Disconnected",
"language": "Language",
"current": "Current"
},
"time": {
"second": "second",
"seconds": "seconds",
"minute": "minute",
"minutes": "minutes",
"hour": "hour",
"hours": "hours",
"day": "day",
"days": "days",
"ago": "ago",
"now": "now",
"today": "today",
"yesterday": "yesterday",
"tomorrow": "tomorrow"
},
"units": {
"pixels": "pixels",
"percent": "percent",
"milliseconds": "milliseconds",
"seconds": "seconds",
"bytes": "bytes",
"kilobytes": "kilobytes",
"megabytes": "megabytes"
}
}

206
i18n/es.json Normal file
View File

@@ -0,0 +1,206 @@
{
"realDemo": {
"title": "Demostración Real",
"subtitle": "Interfaz para demostraciones reales con el sistema RPA Vision V3",
"component": {
"title": "Demostración Real - RPA Vision V3",
"description": "Este componente permitirá probar el sistema RPA en tiempo real.",
"startButton": "Iniciar Demostración"
},
"status": {
"connected": "Conectado",
"disconnected": "Desconectado",
"live": "En Vivo",
"loading": "Cargando...",
"ready": "Listo",
"error": "Error"
},
"connection": {
"notAvailable": "El servidor de demostración real no está disponible.",
"ensureRunning": "Asegúrese de que el script `demo_real_functionality.py` esté ejecutándose.",
"checkConnection": "Verificar Conexión",
"testApi": "Probar API",
"established": "Conexión al servidor de demostración real establecida",
"unavailable": "Servidor de demostración no disponible",
"impossible": "No se puede conectar al servidor de demostración"
},
"screen": {
"title": "Captura de Pantalla en Tiempo Real",
"refresh": "Actualizar",
"loading": "Cargando pantalla...",
"noCapture": "No hay captura disponible"
},
"elements": {
"detected": "Elementos Detectados",
"noText": "Sin texto",
"details": "Detalles del Elemento",
"type": "Tipo",
"text": "Texto",
"position": "Posición",
"confidence": "Confianza",
"none": "Ninguno"
},
"controls": {
"title": "Controles de Demostración",
"createWorkflow": "Crear Flujo de Demostración",
"executeWorkflow": "Ejecutar Flujo",
"executing": "Ejecutando...",
"quickActions": "Acciones Rápidas",
"testClick": "Clic de Prueba (200, 200)",
"clickHere": "Hacer Clic Aquí"
},
"execution": {
"results": "Resultados de Ejecución",
"action": "Acción",
"target": "Objetivo",
"success": "Éxito",
"failure": "Fallo",
"click": "Clic",
"workflow": "Flujo",
"executed": "ejecutado",
"steps": "pasos",
"workflowSuccess": "Flujo ejecutado con éxito",
"workflowFailure": "Fallo en la ejecución del flujo"
},
"workflow": {
"demo": {
"name": "Demostración Simple",
"step1": "Esperar 1 segundo",
"step2": "Hacer clic en (100, 100)",
"step3": "Esperar 2 segundos"
}
},
"actions": {
"cancel": "Cancelar",
"execute": "Ejecutar",
"close": "Cerrar",
"save": "Guardar"
},
"messages": {
"actionExecuted": "Acción ejecutada",
"actionFailed": "Acción falló",
"workflowStarted": "Iniciando ejecución del flujo",
"workflowCompleted": "Flujo ejecutado con éxito",
"workflowFailed": "Fallo en la ejecución del flujo",
"noConnection": "Sin conexión al servidor de demostración",
"executionError": "Error de ejecución",
"captureStarted": "Captura de pantalla en tiempo real iniciada",
"captureStopped": "Captura de pantalla en tiempo real detenida"
}
},
"realDemoTab": {
"title": "Demostración Real",
"tabs": {
"demo": "Demostración",
"config": "Configuración",
"help": "Ayuda"
},
"serverUnavailable": {
"title": "Servidor de Demostración No Disponible",
"description": "El servidor de demostración real no está ejecutándose. Para usar esta funcionalidad, necesita iniciar el servidor de demostración.",
"howToStart": "Cómo iniciar la demostración:",
"option1": "Opción 1 - Script automático:",
"option2": "Opción 2 - Inicio manual:",
"terminal1": "Terminal 1 - Backend",
"terminal2": "Terminal 2 - Servidor de demostración",
"terminal3": "Terminal 3 - Frontend",
"checkAgain": "Verificar de Nuevo"
},
"config": {
"title": "Configuración de Demostración",
"servicesStatus": "Estado de Servicios",
"backendFlask": "Backend Flask (5002)",
"demoServer": "Servidor Demo (5003)",
"frontendReact": "Frontend React (3000)",
"captureSettings": "Configuración de Captura",
"captureFrequency": "Frecuencia de captura: 1 segundo",
"autoDetection": "Detección automática de elementos UI",
"dataSaving": "Guardando capturas en data/demo/",
"security": "Seguridad",
"securityWarning": "La demostración real puede ejecutar acciones en su sistema. Use solo en un entorno de prueba seguro."
},
"help": {
"title": "Guía de Uso de Demostración Real",
"objective": {
"title": "Objetivo",
"description": "La demostración real permite probar el sistema RPA Vision V3 con interacciones reales en su pantalla. Puede ver la detección de elementos en tiempo real y ejecutar acciones automatizadas."
},
"features": {
"title": "Funcionalidades",
"realTimeCapture": "Captura en tiempo real: Su pantalla se captura cada segundo",
"uiDetection": "Detección UI: Los elementos interactivos se detectan automáticamente",
"actionExecution": "Ejecución de acciones: Haga clic en elementos detectados para probarlos",
"demoWorkflows": "Flujos de demostración: Cree y ejecute secuencias de acciones",
"history": "Historial: Siga los resultados de sus pruebas"
},
"precautions": {
"title": "Precauciones",
"testEnvironment": "Use solo en un entorno de prueba",
"realActions": "Las acciones se ejecutan realmente en su sistema",
"closeApps": "Cierre aplicaciones importantes antes de probar",
"backupData": "Respalde sus datos importantes"
},
"quickStart": {
"title": "Inicio Rápido",
"step1": "Ejecute el script: python start_real_demo.py",
"step2": "Espere a que todos los servicios inicien",
"step3": "Abra la pestaña \"Demostración\"",
"step4": "Haga clic en \"Crear Flujo de Demostración\"",
"step5": "Pruebe las funcionalidades disponibles"
}
}
},
"common": {
"loading": "Cargando...",
"error": "Error",
"success": "Éxito",
"warning": "Advertencia",
"info": "Información",
"ok": "OK",
"cancel": "Cancelar",
"save": "Guardar",
"delete": "Eliminar",
"edit": "Editar",
"create": "Crear",
"update": "Actualizar",
"refresh": "Actualizar",
"close": "Cerrar",
"open": "Abrir",
"yes": "Sí",
"no": "No",
"enabled": "Habilitado",
"disabled": "Deshabilitado",
"active": "Activo",
"inactive": "Inactivo",
"online": "En línea",
"offline": "Fuera de línea",
"connected": "Conectado",
"disconnected": "Desconectado",
"language": "Idioma",
"current": "Actual"
},
"time": {
"second": "segundo",
"seconds": "segundos",
"minute": "minuto",
"minutes": "minutos",
"hour": "hora",
"hours": "horas",
"day": "día",
"days": "días",
"ago": "hace",
"now": "ahora",
"today": "hoy",
"yesterday": "ayer",
"tomorrow": "mañana"
},
"units": {
"pixels": "píxeles",
"percent": "por ciento",
"milliseconds": "milisegundos",
"seconds": "segundos",
"bytes": "bytes",
"kilobytes": "kilobytes",
"megabytes": "megabytes"
}
}

206
i18n/fr.json Normal file
View File

@@ -0,0 +1,206 @@
{
"realDemo": {
"title": "Démonstration Réelle",
"subtitle": "Interface pour faire de vraies démonstrations avec le système RPA Vision V3",
"component": {
"title": "Démonstration Réelle - RPA Vision V3",
"description": "Ce composant permettra de tester le système RPA en temps réel.",
"startButton": "Démarrer la Démonstration"
},
"status": {
"connected": "Connecté",
"disconnected": "Non Connecté",
"live": "En Direct",
"loading": "Chargement...",
"ready": "Prêt",
"error": "Erreur"
},
"connection": {
"notAvailable": "Le serveur de démonstration réelle n'est pas disponible.",
"ensureRunning": "Assurez-vous que le script `demo_real_functionality.py` est en cours d'exécution.",
"checkConnection": "Vérifier la Connexion",
"testApi": "Tester l'API",
"established": "Connexion au serveur de démonstration réelle établie",
"unavailable": "Serveur de démonstration non disponible",
"impossible": "Impossible de se connecter au serveur de démonstration"
},
"screen": {
"title": "Capture d'Écran en Temps Réel",
"refresh": "Actualiser",
"loading": "Chargement de l'écran...",
"noCapture": "Aucune capture disponible"
},
"elements": {
"detected": "Éléments Détectés",
"noText": "Sans texte",
"details": "Détails de l'Élément",
"type": "Type",
"text": "Texte",
"position": "Position",
"confidence": "Confiance",
"none": "Aucun"
},
"controls": {
"title": "Contrôles de Démonstration",
"createWorkflow": "Créer Workflow de Démo",
"executeWorkflow": "Exécuter Workflow",
"executing": "Exécution...",
"quickActions": "Actions Rapides",
"testClick": "Clic Test (200, 200)",
"clickHere": "Cliquer Ici"
},
"execution": {
"results": "Résultats d'Exécution",
"action": "Action",
"target": "Cible",
"success": "Succès",
"failure": "Échec",
"click": "Clic",
"workflow": "Workflow",
"executed": "exécuté",
"steps": "étapes",
"workflowSuccess": "Workflow exécuté avec succès",
"workflowFailure": "Échec du workflow"
},
"workflow": {
"demo": {
"name": "Démonstration Simple",
"step1": "Attendre 1 seconde",
"step2": "Cliquer à (100, 100)",
"step3": "Attendre 2 secondes"
}
},
"actions": {
"cancel": "Annuler",
"execute": "Exécuter",
"close": "Fermer",
"save": "Sauvegarder"
},
"messages": {
"actionExecuted": "Action exécutée",
"actionFailed": "Échec de l'action",
"workflowStarted": "Démarrage de l'exécution du workflow",
"workflowCompleted": "Workflow exécuté avec succès",
"workflowFailed": "Échec du workflow",
"noConnection": "Pas de connexion au serveur de démonstration",
"executionError": "Erreur lors de l'exécution",
"captureStarted": "Capture d'écran en temps réel démarrée",
"captureStopped": "Capture d'écran en temps réel arrêtée"
}
},
"realDemoTab": {
"title": "Démonstration Réelle",
"tabs": {
"demo": "Démonstration",
"config": "Configuration",
"help": "Aide"
},
"serverUnavailable": {
"title": "Serveur de Démonstration Non Disponible",
"description": "Le serveur de démonstration réelle n'est pas en cours d'exécution. Pour utiliser cette fonctionnalité, vous devez démarrer le serveur de démonstration.",
"howToStart": "Comment démarrer la démonstration :",
"option1": "Option 1 - Script automatique :",
"option2": "Option 2 - Démarrage manuel :",
"terminal1": "Terminal 1 - Backend",
"terminal2": "Terminal 2 - Serveur de démonstration",
"terminal3": "Terminal 3 - Frontend",
"checkAgain": "Vérifier à Nouveau"
},
"config": {
"title": "Configuration de la Démonstration",
"servicesStatus": "Statut des Services",
"backendFlask": "Backend Flask (5002)",
"demoServer": "Serveur Démo (5003)",
"frontendReact": "Frontend React (3000)",
"captureSettings": "Paramètres de Capture",
"captureFrequency": "Fréquence de capture : 1 seconde",
"autoDetection": "Détection automatique des éléments UI",
"dataSaving": "Sauvegarde des captures dans data/demo/",
"security": "Sécurité",
"securityWarning": "La démonstration réelle peut exécuter des actions sur votre système. Utilisez uniquement dans un environnement de test sécurisé."
},
"help": {
"title": "Guide d'Utilisation de la Démonstration Réelle",
"objective": {
"title": "Objectif",
"description": "La démonstration réelle permet de tester le système RPA Vision V3 avec de vraies interactions sur votre écran. Vous pouvez voir la détection d'éléments en temps réel et exécuter des actions automatisées."
},
"features": {
"title": "Fonctionnalités",
"realTimeCapture": "Capture en temps réel : Votre écran est capturé toutes les secondes",
"uiDetection": "Détection UI : Les éléments interactifs sont automatiquement détectés",
"actionExecution": "Exécution d'actions : Cliquez sur les éléments détectés pour les tester",
"demoWorkflows": "Workflows de démo : Créez et exécutez des séquences d'actions",
"history": "Historique : Suivez les résultats de vos tests"
},
"precautions": {
"title": "Précautions",
"testEnvironment": "Utilisez uniquement dans un environnement de test",
"realActions": "Les actions sont exécutées réellement sur votre système",
"closeApps": "Fermez les applications importantes avant de tester",
"backupData": "Sauvegardez vos données importantes"
},
"quickStart": {
"title": "Démarrage Rapide",
"step1": "Lancez le script : python start_real_demo.py",
"step2": "Attendez que tous les services démarrent",
"step3": "Ouvrez l'onglet \"Démonstration\"",
"step4": "Cliquez sur \"Créer Workflow de Démo\"",
"step5": "Testez les fonctionnalités disponibles"
}
}
},
"common": {
"loading": "Chargement...",
"error": "Erreur",
"success": "Succès",
"warning": "Avertissement",
"info": "Information",
"ok": "OK",
"cancel": "Annuler",
"save": "Sauvegarder",
"delete": "Supprimer",
"edit": "Modifier",
"create": "Créer",
"update": "Mettre à jour",
"refresh": "Actualiser",
"close": "Fermer",
"open": "Ouvrir",
"yes": "Oui",
"no": "Non",
"enabled": "Activé",
"disabled": "Désactivé",
"active": "Actif",
"inactive": "Inactif",
"online": "En ligne",
"offline": "Hors ligne",
"connected": "Connecté",
"disconnected": "Déconnecté",
"language": "Langue",
"current": "Actuel"
},
"time": {
"second": "seconde",
"seconds": "secondes",
"minute": "minute",
"minutes": "minutes",
"hour": "heure",
"hours": "heures",
"day": "jour",
"days": "jours",
"ago": "il y a",
"now": "maintenant",
"today": "aujourd'hui",
"yesterday": "hier",
"tomorrow": "demain"
},
"units": {
"pixels": "pixels",
"percent": "pourcent",
"milliseconds": "millisecondes",
"seconds": "secondes",
"bytes": "octets",
"kilobytes": "kilo-octets",
"megabytes": "méga-octets"
}
}

View File

@@ -0,0 +1,269 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Validation des Traductions - RPA Vision V3
Auteur : Dom, Alice, Kiro - 7 janvier 2026
Script pour valider la cohérence et la complétude des fichiers de traduction.
"""
import json
import os
from pathlib import Path
from typing import Dict, List, Set, Any
class TranslationValidator:
"""
Validateur pour les fichiers de traduction
"""
def __init__(self, i18n_dir: str = "i18n"):
self.i18n_dir = Path(i18n_dir)
self.config = self.load_config()
self.translations = {}
self.errors = []
self.warnings = []
def load_config(self) -> Dict[str, Any]:
"""Charge la configuration i18n"""
config_path = self.i18n_dir / "config.json"
try:
with open(config_path, 'r', encoding='utf-8') as f:
return json.load(f)
except Exception as e:
self.errors.append(f"Erreur lors du chargement de config.json: {e}")
return {}
def load_translations(self) -> None:
"""Charge tous les fichiers de traduction"""
if not self.config:
return
for lang in self.config.get('supportedLanguages', []):
lang_code = lang['code']
lang_file = self.i18n_dir / f"{lang_code}.json"
try:
with open(lang_file, 'r', encoding='utf-8') as f:
self.translations[lang_code] = json.load(f)
print(f"✅ Chargé: {lang_code}.json")
except FileNotFoundError:
self.errors.append(f"Fichier manquant: {lang_code}.json")
except json.JSONDecodeError as e:
self.errors.append(f"JSON invalide dans {lang_code}.json: {e}")
except Exception as e:
self.errors.append(f"Erreur lors du chargement de {lang_code}.json: {e}")
def get_all_keys(self, obj: Dict[str, Any], prefix: str = "") -> Set[str]:
"""Extrait toutes les clés d'un objet JSON imbriqué"""
keys = set()
for key, value in obj.items():
full_key = f"{prefix}.{key}" if prefix else key
if isinstance(value, dict):
keys.update(self.get_all_keys(value, full_key))
else:
keys.add(full_key)
return keys
def validate_structure(self) -> None:
"""Valide la structure des fichiers de traduction"""
if not self.translations:
self.errors.append("Aucun fichier de traduction chargé")
return
# Obtenir les clés de référence (langue par défaut)
default_lang = self.config.get('defaultLanguage', 'fr')
if default_lang not in self.translations:
self.errors.append(f"Langue par défaut '{default_lang}' non trouvée")
return
reference_keys = self.get_all_keys(self.translations[default_lang])
print(f"📋 Clés de référence ({default_lang}): {len(reference_keys)}")
# Vérifier chaque langue
for lang_code, translations in self.translations.items():
if lang_code == default_lang:
continue
lang_keys = self.get_all_keys(translations)
# Clés manquantes
missing_keys = reference_keys - lang_keys
if missing_keys:
self.errors.append(f"Clés manquantes dans {lang_code}: {sorted(missing_keys)}")
# Clés supplémentaires
extra_keys = lang_keys - reference_keys
if extra_keys:
self.warnings.append(f"Clés supplémentaires dans {lang_code}: {sorted(extra_keys)}")
print(f"🔍 {lang_code}: {len(lang_keys)} clés ({len(missing_keys)} manquantes, {len(extra_keys)} supplémentaires)")
def validate_placeholders(self) -> None:
"""Valide les placeholders dans les traductions"""
import re
placeholder_pattern = re.compile(r'\{\{(\w+)\}\}')
for lang_code, translations in self.translations.items():
self._validate_placeholders_recursive(translations, lang_code, placeholder_pattern)
def _validate_placeholders_recursive(self, obj: Dict[str, Any], lang_code: str, pattern, prefix: str = "") -> None:
"""Valide récursivement les placeholders"""
for key, value in obj.items():
full_key = f"{prefix}.{key}" if prefix else key
if isinstance(value, dict):
self._validate_placeholders_recursive(value, lang_code, pattern, full_key)
elif isinstance(value, str):
placeholders = pattern.findall(value)
if placeholders:
# Vérifier la cohérence avec la langue de référence
default_lang = self.config.get('defaultLanguage', 'fr')
if lang_code != default_lang and default_lang in self.translations:
ref_value = self._get_nested_value(self.translations[default_lang], full_key.split('.'))
if ref_value:
ref_placeholders = pattern.findall(ref_value)
if set(placeholders) != set(ref_placeholders):
self.warnings.append(
f"Placeholders différents dans {lang_code}.{full_key}: "
f"{placeholders} vs {ref_placeholders}"
)
def _get_nested_value(self, obj: Dict[str, Any], keys: List[str]) -> str:
"""Obtient une valeur imbriquée"""
current = obj
for key in keys:
if isinstance(current, dict) and key in current:
current = current[key]
else:
return ""
return current if isinstance(current, str) else ""
def validate_empty_values(self) -> None:
"""Valide qu'il n'y a pas de valeurs vides"""
for lang_code, translations in self.translations.items():
self._validate_empty_recursive(translations, lang_code)
def _validate_empty_recursive(self, obj: Dict[str, Any], lang_code: str, prefix: str = "") -> None:
"""Valide récursivement les valeurs vides"""
for key, value in obj.items():
full_key = f"{prefix}.{key}" if prefix else key
if isinstance(value, dict):
self._validate_empty_recursive(value, lang_code, full_key)
elif isinstance(value, str):
if not value.strip():
self.warnings.append(f"Valeur vide dans {lang_code}.{full_key}")
def validate_config(self) -> None:
"""Valide la configuration"""
required_fields = ['defaultLanguage', 'supportedLanguages', 'fallbackLanguage']
for field in required_fields:
if field not in self.config:
self.errors.append(f"Champ manquant dans config.json: {field}")
# Vérifier les langues supportées
if 'supportedLanguages' in self.config:
for i, lang in enumerate(self.config['supportedLanguages']):
required_lang_fields = ['code', 'name', 'flag', 'currency']
for field in required_lang_fields:
if field not in lang:
self.errors.append(f"Champ manquant dans supportedLanguages[{i}]: {field}")
# Vérifier que la langue par défaut est supportée
default_lang = self.config.get('defaultLanguage')
supported_codes = [lang['code'] for lang in self.config.get('supportedLanguages', [])]
if default_lang and default_lang not in supported_codes:
self.errors.append(f"Langue par défaut '{default_lang}' non dans supportedLanguages")
def generate_report(self) -> str:
"""Génère un rapport de validation"""
report = []
report.append("=" * 60)
report.append("RAPPORT DE VALIDATION DES TRADUCTIONS")
report.append("=" * 60)
report.append("")
# Statistiques
report.append("📊 STATISTIQUES:")
report.append(f" • Langues configurées: {len(self.config.get('supportedLanguages', []))}")
report.append(f" • Fichiers chargés: {len(self.translations)}")
report.append(f" • Erreurs trouvées: {len(self.errors)}")
report.append(f" • Avertissements: {len(self.warnings)}")
report.append("")
# Erreurs
if self.errors:
report.append("❌ ERREURS:")
for error in self.errors:
report.append(f"{error}")
report.append("")
# Avertissements
if self.warnings:
report.append("⚠️ AVERTISSEMENTS:")
for warning in self.warnings:
report.append(f"{warning}")
report.append("")
# Résumé
if not self.errors and not self.warnings:
report.append("✅ VALIDATION RÉUSSIE: Aucun problème détecté!")
elif not self.errors:
report.append("✅ VALIDATION RÉUSSIE: Quelques avertissements mineurs")
else:
report.append("❌ VALIDATION ÉCHOUÉE: Des erreurs doivent être corrigées")
report.append("")
report.append("=" * 60)
return "\n".join(report)
def run_validation(self) -> bool:
"""Exécute toutes les validations"""
print("🔍 Démarrage de la validation des traductions...")
print()
# Validation de la configuration
print("📋 Validation de la configuration...")
self.validate_config()
# Chargement des traductions
print("📂 Chargement des fichiers de traduction...")
self.load_translations()
if not self.translations:
print("❌ Aucun fichier de traduction chargé")
return False
# Validations
print("🔍 Validation de la structure...")
self.validate_structure()
print("🔍 Validation des placeholders...")
self.validate_placeholders()
print("🔍 Validation des valeurs vides...")
self.validate_empty_values()
# Génération du rapport
print()
print(self.generate_report())
return len(self.errors) == 0
def main():
"""Point d'entrée principal"""
validator = TranslationValidator()
success = validator.run_validation()
return 0 if success else 1
if __name__ == "__main__":
exit(main())