From 7e3d0d1f88263e0228231f080fd77c6c1a81a1d1 Mon Sep 17 00:00:00 2001 From: Mathieu Benoit Date: Mon, 14 Sep 2026 14:41:19 -0400 Subject: [PATCH] =?UTF-8?q?[IMP]=20menu=20proxmox=20:=20une=20ic=C3=B4ne?= =?UTF-8?q?=20=C3=A0=20chaque=20entr=C3=A9e=20qui=20n'en=20portait=20pas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ten of the eighteen entries carried no pictogram, and the eye picks one out of such a list before it reads. Each takes the icon its siblings already use elsewhere in the tool — 📋 lists, 🧹 cleans, 📊 measures, 🔍 previews, 📥 downloads, 🗂 catalogues, 🖥 tunnels a desktop — so the same picture keeps meaning the same thing from one menu to the next. A table in the tests holds the pairing, in both languages, and checks the menu still shows the entries it freezes. --- FR --- Dix des dix-huit entrées ne portaient aucun pictogramme, et l'œil s'y repère avant de lire. Chacune reçoit l'icône que ses semblables portent déjà ailleurs dans l'outil — 📋 liste, 🧹 nettoie, 📊 mesure, 🔍 prévisualise, 📥 télécharge, 🗂 catalogue, 🖥 ouvre un bureau —, si bien qu'une même image garde le même sens d'un menu à l'autre. Un tableau dans les tests fige le couple, dans les deux langues, et vérifie que le menu affiche encore les entrées qu'il fige. Assisted-by: Claude Opus 5 --- script/todo/todo_i18n.py | 44 +++++++++++++++---------------- test/test_todo_menu.py | 56 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 22 deletions(-) diff --git a/script/todo/todo_i18n.py b/script/todo/todo_i18n.py index dbc9fa0..7ae5c1b 100644 --- a/script/todo/todo_i18n.py +++ b/script/todo/todo_i18n.py @@ -4338,48 +4338,48 @@ TRANSLATIONS = { "en": "Selection (number): ", }, "Deploy a VM on the Proxmox host": { - "fr": "Déployer une VM sur l'hôte Proxmox", - "en": "Deploy a VM on the Proxmox host", + "fr": "🚀 Déployer une VM sur l'hôte Proxmox", + "en": "🚀 Deploy a VM on the Proxmox host", }, "Preview a deployment (dry-run, nothing sent)": { - "fr": "Prévisualiser un déploiement (dry-run, rien n'est envoyé)", - "en": "Preview a deployment (dry-run, nothing sent)", + "fr": "🔍 Prévisualiser un déploiement (dry-run, rien n'est envoyé)", + "en": "🔍 Preview a deployment (dry-run, nothing sent)", }, "Download a cloud image on the host": { - "fr": "Télécharger une image cloud sur l'hôte", - "en": "Download a cloud image on the host", + "fr": "📥 Télécharger une image cloud sur l'hôte", + "en": "📥 Download a cloud image on the host", }, "List VMs (qm list)": { - "fr": "Lister les VM (qm list)", - "en": "List VMs (qm list)", + "fr": "📋 Lister les VM (qm list)", + "en": "📋 List VMs (qm list)", }, "Clean up (orphan disks)": { - "fr": "Nettoyer (disques orphelins)", - "en": "Clean up (orphan disks)", + "fr": "🧹 Nettoyer (disques orphelins)", + "en": "🧹 Clean up (orphan disks)", }, "Statistics (host and VMs)": { - "fr": "Statistiques (hôte et VM)", - "en": "Statistics (host and VMs)", + "fr": "📊 Statistiques (hôte et VM)", + "en": "📊 Statistics (host and VMs)", }, "Remote desktop tunnel (VNC/RDP over SSH)": { - "fr": "Tunnel bureau distant (VNC/RDP par SSH)", - "en": "Remote desktop tunnel (VNC/RDP over SSH)", + "fr": "🖥 Tunnel bureau distant (VNC/RDP par SSH)", + "en": "🖥 Remote desktop tunnel (VNC/RDP over SSH)", }, "List available images and their specs": { - "fr": "Lister les images disponibles et leurs specs", - "en": "List available images and their specs", + "fr": "🗂 Lister les images disponibles et leurs specs", + "en": "🗂 List available images and their specs", }, "Proxmox - example sequence (dry-run)": { - "fr": "Proxmox - exemple de séquence (dry-run)", - "en": "Proxmox - example sequence (dry-run)", + "fr": "🎬 Proxmox - exemple de séquence (dry-run)", + "en": "🎬 Proxmox - example sequence (dry-run)", }, "Host": { - "fr": "Hôte", - "en": "Host", + "fr": "🏠 Hôte", + "en": "🏠 Host", }, "Change the Proxmox host": { - "fr": "Changer d'hôte Proxmox", - "en": "Change the Proxmox host", + "fr": "🔀 Changer d'hôte Proxmox", + "en": "🔀 Change the Proxmox host", }, "VM name (default: erplibre-): ": { "fr": "Nom de la VM (défaut : erplibre-) : ", diff --git a/test/test_todo_menu.py b/test/test_todo_menu.py index 7c8a3b1..84889ce 100644 --- a/test/test_todo_menu.py +++ b/test/test_todo_menu.py @@ -296,6 +296,62 @@ class TestLaParitéProxmox(unittest.TestCase): self.assertIn("execute_from_configuration", self.src) +class TestLesIconesDuMenuProxmox(unittest.TestCase): + """L'icône vit DANS la chaîne traduite, et les deux langues la portent. + + Une entrée sans icône se perd dans une liste de dix-huit : l'œil s'y + repère par le pictogramme avant de lire. Le même pictogramme dit la même + chose partout dans l'outil — 📋 liste, 🧹 nettoie, 📊 mesure — et ce + tableau est ce qui l'empêche de dériver d'un menu à l'autre. + """ + + ICONES = { + "Deploy a VM on the Proxmox host": "🚀", + "Preview a deployment (dry-run, nothing sent)": "🔍", + "Download a cloud image on the host": "📥", + "Reopen install monitoring (last run / history)": "📈", + "List VMs (qm list)": "📋", + "Show a VM IP address": "🌐", + "Open the console on a VM": "🖥", + "Resize a VM disk": "📐", + "Delete VM(s)": "🗑", + "Clean up (orphan disks)": "🧹", + "Test a VM (open Odoo in a CLI browser)": "🧪", + "Statistics (host and VMs)": "📊", + "SSH configuration (~/.ssh/config, ProxyJump)": "🔑", + "Remote desktop tunnel (VNC/RDP over SSH)": "🖥", + "Android emulator (start, tunnel, scrcpy)": "📱", + "List available images and their specs": "🗂", + "Proxmox - example sequence (dry-run)": "🎬", + "Change the Proxmox host": "🔀", + "Host": "🏠", + } + + def test_chaque_entree_porte_son_icone(self): + from script.todo import todo_i18n + + for cle, icone in self.ICONES.items(): + entree = todo_i18n.TRANSLATIONS[cle] + for langue in ("fr", "en"): + self.assertTrue( + entree[langue].startswith(icone), + f"« {cle} » ({langue}) ne commence pas par {icone} :" + f" {entree[langue]}", + ) + + def test_le_menu_affiche_bien_ces_entrees(self): + """Le tableau ci-dessus ne vaut que s'il décrit le menu RÉEL : une + entrée renommée le laisserait figer une icône que personne ne voit.""" + src = (TODO_DIR / "proxmox_menu.py").read_text(encoding="utf-8") + for cle in self.ICONES: + # La chaîne SEULE : une entrée longue s'écrit « t( » sur une + # ligne et sa chaîne sur la suivante, et chercher l'appel entier + # ne trouverait que les courtes. + self.assertIn( + f'"{cle}"', src, f"« {cle} » n'est plus dans le menu" + ) + + class TestLArbreDesMenus(unittest.TestCase): """L'écran de télémétrie lit le CODE, pas la classe assemblée.