From 82f6b4a791fae8f186984e2d02050b28af066f17 Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Fri, 18 Sep 2026 10:14:38 -0400 Subject: [PATCH] fix: icones manquantes dans la table des matieres de la configuration (BUG-066) --- CHANGELOG.md | 16 +++++++++++++++- README.fr.md | 6 +++--- README.md | 6 +++--- VERSION | 2 +- desktop/Cargo.lock | 2 +- desktop/Cargo.toml | 2 +- desktop/tauri.conf.json | 2 +- docs/ISSUES_TODOLIST.md | 2 ++ docs/ROADMAP.md | 2 +- frontend/locales/en.json | 2 +- frontend/locales/fr.json | 4 ++-- package.json | 2 +- tests/frontend/unit.test.mjs | 33 +++++++++++++++++++++++++++++++++ 13 files changed, 65 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6794ed5..77934fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ Format basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/), et [Semantic Versioning](https://semver.org/spec/v2.0.0.html). > **En cours de développement** : les changements à venir sont listés dans la section -> [Unreleased](#unreleased). La dernière version livrée est **2.12.1**. +> [Unreleased](#unreleased). La dernière version livrée est **2.12.2**. --- @@ -14,6 +14,20 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html). --- +## [2.12.2] — 2026-09-18 + +### Corrigé + +- **BUG-066 — Configuration : icônes manquantes dans la table des matières** : + les entrées « Fichiers cachés » et « Partages publics » du sommaire de la page de + configuration n'affichaient pas d'icône (les titres de section, eux, en avaient une). + Les libellés i18n `config.section_hidden` (🗂️) et `config.section_shares` (📤) sont + alignés sur leurs titres de section, en FR **et** EN. Test de non-régression ajouté + dans `tests/frontend/unit.test.mjs` (toutes les entrées du sommaire doivent porter une + icône dans les deux langues). + +--- + ## [2.12.1] — 2026-09-18 --- diff --git a/README.fr.md b/README.fr.md index 5445a39..1952e38 100644 --- a/README.fr.md +++ b/README.fr.md @@ -4,7 +4,7 @@ **Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive. -[![Version](https://img.shields.io/badge/Version-2.12.1-blue.svg)]() +[![Version](https://img.shields.io/badge/Version-2.12.2-blue.svg)]() [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/) [![Python](https://img.shields.io/badge/Python-3.11+-green.svg)](https://www.python.org/) @@ -926,8 +926,8 @@ Ce projet est sous licence **MIT** — voir le fichier [LICENSE](LICENSE) pour l ## 📝 Changelog -Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.12.1). +Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.12.2). --- -*Projet : ObsiGate | Version : 2.12.1 | Dernière mise à jour : Juin 2026* +*Projet : ObsiGate | Version : 2.12.2 | Dernière mise à jour : Juin 2026* diff --git a/README.md b/README.md index e63ee19..e518227 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **Ultra-light web gateway for your Obsidian vaults** — Access, browse, and search all your Obsidian notes from any device via a modern, responsive web interface. -[![Version](https://img.shields.io/badge/Version-2.12.1-blue.svg)]() +[![Version](https://img.shields.io/badge/Version-2.12.2-blue.svg)]() [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/) [![Python](https://img.shields.io/badge/Python-3.11+-green.svg)](https://www.python.org/) @@ -1095,8 +1095,8 @@ This project is licensed under the **MIT License** - see the [LICENSE](LICENSE) ## 📝 Changelog -See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.12.1). +See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.12.2). --- -*Project: ObsiGate | Version: 2.12.1 | Last updated: May 2026* +*Project: ObsiGate | Version: 2.12.2 | Last updated: May 2026* diff --git a/VERSION b/VERSION index 3cf561c..371a952 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.12.1 +2.12.2 diff --git a/desktop/Cargo.lock b/desktop/Cargo.lock index 5bd7646..03a6dc5 100644 --- a/desktop/Cargo.lock +++ b/desktop/Cargo.lock @@ -2626,7 +2626,7 @@ dependencies = [ [[package]] name = "obsigate-desktop" -version = "2.12.1" +version = "2.12.2" dependencies = [ "chrono", "env_logger", diff --git a/desktop/Cargo.toml b/desktop/Cargo.toml index 0d8de12..cd59cae 100644 --- a/desktop/Cargo.toml +++ b/desktop/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "obsigate-desktop" -version = "2.12.1" +version = "2.12.2" description = "ObsiGate Desktop — Porte d'entrée native pour vos vaults Obsidian" authors = ["Bruno Charest"] edition = "2021" diff --git a/desktop/tauri.conf.json b/desktop/tauri.conf.json index 0bca5af..8425242 100644 --- a/desktop/tauri.conf.json +++ b/desktop/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://raw.githubusercontent.com/nicedoc/obsigate/main/desktop/tauri.conf.schema.json", "productName": "ObsiGate", - "version": "2.12.1", + "version": "2.12.2", "identifier": "com.obsigate.desktop", "build": { "frontendDist": "../frontend", diff --git a/docs/ISSUES_TODOLIST.md b/docs/ISSUES_TODOLIST.md index c9616d8..77bd776 100644 --- a/docs/ISSUES_TODOLIST.md +++ b/docs/ISSUES_TODOLIST.md @@ -174,6 +174,7 @@ Avant de corriger quoi que ce soit, un agent IA doit : | *BUG-063* | [🟡 IMPORTANT] Viewer PDF : la table des matières s'affiche mais ne navigue pas | 🟢 corrigé | P1 | 📱 frontend | IA | `frontend/js/viewer.js`, `tests/frontend/pdf-viewer.test.mjs`, `tests/e2e/pdf-viewer.spec.js` (fixture `test_vault/sample-pdf-toc.pdf`) | Ouvrir un PDF avec signets, puis cliquer une entrée de la TOC | Deux causes : (1) `contentWindow.location.hash='page=N'` n'atteint pas le document (lecteur PDF natif dans une fenêtre `about:blank`) ; (2) un simple changement de fragment sur `iframe.src` est une navigation same-document **ignorée** par le lecteur natif. `navigatePdfToPage()` (liens `data-page` + listeners, plus d'`onclick` inline) recharge réellement l'iframe via un paramètre de query qui change (`&_pdfpage=#page=N`). Test E2E : `src` finit par `&_pdfpage=#page=3`. Vérifié en Chrome *headful* : page 1 → page 8 → page 1 (captures identiques au retour) | Le fragment seul ne suffisait pas : Chrome applique `#page=N` au **chargement**, pas lors d'un changement de fragment | | *BUG-064* | [🟡 IMPORTANT] Éditeur Excalidraw : le diagramme ne s'affiche jamais (canvas vide), pour tout fichier `.excalidraw` / `.excalidraw.md` | 🟢 corrigé | P1 | 📱 frontend + ⚙️ backend | IA | `frontend/excalidraw-editor.html`, `backend/main.py`, `tests/frontend/excalidraw-viewer.test.mjs`, `tests/test_security_hardening.py`, `tests/e2e/excalidraw.spec.js`, `test_vault/diagram-app-export.excalidraw` | Ouvrir un `.excalidraw` (ou `.excalidraw.md`) dans ObsiGate | Deux causes : (1) la feuille de style d'Excalidraw n'était jamais chargée → éditeur non stylisé + `.excalidraw` sans hauteur fixe → boucle de resize jusqu'au plafond `2^25` (33 554 432 px) → scène blanche. Correctif : `` CSS depuis esm.sh + `style-src` CSP autorisant `https://esm.sh`. (2) `appState.collaborators` objet JSON → `collaborators.forEach is not a function` ; `sanitizeAppState()` reconvertit en `Map` et écarte `width/height/offsetLeft/offsetTop`. | Vérifié navigateur : hauteur canvas 525 px (avant 33 554 432), dessin affiché, UI stylisée, 0 erreur. E2E + tests statiques CSP/CSS ajoutés. | | *BUG-065* | [🟡 IMPORTANT] Éditeur Excalidraw : l'auto-save recharge la page en pleine édition | 🟢 corrigé | P1 | 📱 frontend | IA | `frontend/js/excalidraw-viewer.js`, `frontend/js/utils.js`, `frontend/excalidraw-editor.html`, `tests/frontend/excalidraw-viewer.test.mjs` | Ouvrir un `.excalidraw` puis modifier un élément : au bout de 2 s la vue se recharge | Chaque modification déclenchait un `PUT save` 2 s plus tard → SSE `index_updated` → `reloadExternalWrite` → `openFile` → **recréation de l'iframe** (refresh visible). Auto-save supprimée : sauvegarde explicite (bouton 💾 / Ctrl+S). `reloadExternalWrite` ignore le fichier si un iframe Excalidraw est ouvert (`iframe[data-excalidraw-vault/path]`). Le badge « Modified » ne réagit plus aux changements d'`appState` (resize/zoom) mais à la signature des éléments. | Vérifié Playwright : plus de refresh, badge stable après bascule plein écran. Test statique (absence de `requestSave`/`saveTimer`). | +| *BUG-066* | [🔵 MINEUR] Configuration : icônes manquantes dans la table des matières (« Fichiers cachés », « Partages publics ») | 🟢 corrigé | P3 | 📱 frontend | IA | `frontend/locales/{fr,en}.json` | Ouvrir Configuration → observer le sommaire : les entrées « Fichiers cachés » et « Partages publics » n'ont pas d'icône | `config.section_hidden` → « 🗂️ Fichiers cachés » / « 🗂️ Hidden files », `config.section_shares` → « 📤 Partages publics » (EN avait déjà l'icône). Test : `tests/frontend/unit.test.mjs` (+1 : toutes les entrées du sommaire portent une icône FR/EN) | Les libellés du sommaire utilisent des clés i18n distinctes des titres de section (`auto.f8ba6127`, `config.section_partages-publics`) qui, elles, avaient l'icône | | | | | | | | | | | | | ### TODOs techniques (améliorations / nouvelles tâches) @@ -244,6 +245,7 @@ Avant de corriger quoi que ce soit, un agent IA doit : | 2026-09-17 | BUG-064 (complément) | Correction | `frontend/style.css`, `tests/frontend/excalidraw-viewer.test.mjs`, `CHANGELOG.md`, `docs/ISSUES_TODOLIST.md` | **BUG-064 (complément)** : quand la barre de navigation gauche est masquée, le viewer Excalidraw restait borné à la colonne de lecture centrée de 1200 px. La règle `.sidebar.hidden ~ .content-wrapper .content-area { max-width: 1200px }` s'appliquait au viewer comme aux notes. Ajout de `.content-area:has(iframe[src*="excalidraw-editor.html"])` en `max-width: none; margin: 0` (même traitement que les viewers PDF/image, BUG-062). Vérifié Playwright (viewport 1400 px) : contenu 1115 → 1400 px, iframe 1035 → 1320 px, `max-width` calculé `none`. Test statique ajouté (`excalidraw-viewer.test.mjs` 9/9). | 🟢 corrigé (en attente vérif utilisateur) | | 2026-09-17 | BUG-065, #78 (complément) | Correction + feature | `frontend/js/excalidraw-viewer.js`, `frontend/js/utils.js`, `frontend/excalidraw-editor.html`, `tests/frontend/excalidraw-viewer.test.mjs`, `docs/features/excalidraw.md`, `CHANGELOG.md`, `docs/ISSUES_TODOLIST.md` | **BUG-065** : l'auto-save Excalidraw (débounce 2 s) déclenchait `PUT save` → SSE `index_updated` → `reloadExternalWrite` → `openFile` → recréation de l'iframe = refresh visible pendant le dessin. Auto-save retirée (`excalidraw-viewer.js` : plus de `requestSave`/`saveTimer`), sauvegarde explicite (bouton 💾 / Ctrl+S) ; `reloadExternalWrite` (utils.js) court-circuite le re-rendu si un iframe Excalidraw est ouvert sur ce fichier (attributs `data-excalidraw-vault`/`data-excalidraw-path`) ; le badge « Modified » suit désormais une signature des éléments (`id:versionNonce`) au lieu de tout `onChange` — resize/zoom/plein écran ne marquent plus le fichier modifié. **#78 (complément)** : bouton **plein écran** `#btn-fullscreen` dans la barre d'outils de l'éditeur (`requestFullscreen` sur le document de l'iframe) + iframe créée avec `allow="fullscreen" allowfullscreen`. Vérifié Playwright : bascule plein écran OK (`document.fullscreenElement` true→false), badge non modifié après bascule ; tests statiques `excalidraw-viewer.test.mjs` 12/12, validate-imports 38 modules, unit 9/9. | 🟢 corrigé (en attente vérif utilisateur) | | 2026-09-17 | #78 (complément) | UI | `frontend/excalidraw-editor.html`, `docs/features/excalidraw.md`, `CHANGELOG.md` | **#78 (complément)** : la barre d'outils de l'éditeur Excalidraw passe en **colonne d'icônes** (34×34 px, SVG seuls), **collée au bord droit** (`right: 0` ; `top: 45%` ; empilement vertical), avec `title`/`aria-label`. L'icône du bouton Save est remplacée par une coche pendant 1,2 s après une sauvegarde réussie. Badge « Modifié » réduit à une pastille. Vérifié Playwright : bord droit au bord de l'iframe, haut 45 %, 4 boutons empilés ; bascule plein écran OK, cycle d'icône Save + `PUT save` observés. | 🟢 livré (en attente vérif utilisateur) | +| 2026-09-18 | BUG-066 | Correction | `frontend/locales/fr.json`, `frontend/locales/en.json`, `tests/frontend/unit.test.mjs`, `CHANGELOG.md`, `docs/ISSUES_TODOLIST.md` | **BUG-066** : la table des matières de la page de configuration n'affichait aucune icône pour « Fichiers cachés » et « Partages publics ». Les libellés du sommaire proviennent de clés i18n (`config.section_hidden`, `config.section_shares`) distinctes des titres de section qui, eux, portaient déjà l'icône. Alignement : 🗂️ / 📤 en FR **et** EN. Test de non-régression : `unit.test.mjs` vérifie que **toutes** les entrées `.help-nav-link` du sommaire portent une icône dans les deux langues (17/17). Vérifié : `unit.test.mjs` 10/10, `validate-imports` 38 modules. | 🟢 corrigé (en attente vérif utilisateur) | --- diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 5e18aa7..d73458f 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -1,6 +1,6 @@ # ObsiGate — Roadmap -> **Version :** 2.12.1 | **Dernière mise à jour :** 2026-09-18 +> **Version :** 2.12.2 | **Dernière mise à jour :** 2026-09-18 > **Ce fichier ne contient que le travail à venir** (🔵 En cours + ⚪ Backlog) et un index compact > vers les fonctionnalités livrées. > - **Méthode de livraison à appliquer pour toute tâche : [DELIVERY_WORKFLOW.md](./DELIVERY_WORKFLOW.md)** diff --git a/frontend/locales/en.json b/frontend/locales/en.json index a7a58cc..ddd829e 100644 --- a/frontend/locales/en.json +++ b/frontend/locales/en.json @@ -496,7 +496,7 @@ "config.section_fonctionnalites": "Features", "config.section_format-du-payload": "Format du payload", "config.section_gestion-des-onglets": "📑 Gestion des onglets", - "config.section_hidden": "Hidden files", + "config.section_hidden": "🗂️ Hidden files", "config.section_historique-recent-redemarrage-non-requis": "📋 Recent History\n No restart required", "config.section_indicateurs-visuels": "Indicateurs visuels", "config.section_intelligence-artificielle-dans-l-editeur": "🤖 AI in the Editor", diff --git a/frontend/locales/fr.json b/frontend/locales/fr.json index 0a506fc..a73dfbb 100644 --- a/frontend/locales/fr.json +++ b/frontend/locales/fr.json @@ -496,7 +496,7 @@ "config.section_fonctionnalites": "Fonctionnalités", "config.section_format-du-payload": "Format du payload", "config.section_gestion-des-onglets": "📑 Gestion des onglets", - "config.section_hidden": "Fichiers cachés", + "config.section_hidden": "🗂️ Fichiers cachés", "config.section_historique-recent-redemarrage-non-requis": "📋 Historique récent\n Redémarrage non requis", "config.section_indicateurs-visuels": "Indicateurs visuels", "config.section_intelligence-artificielle-dans-l-editeur": "🤖 Intelligence Artificielle dans l'Éditeur", @@ -539,7 +539,7 @@ "config.section_securite-signature-hmac-sha256": "Sécurité : signature HMAC-SHA256", "config.section_selection-de-vault": "Sélection de vault", "config.section_server": "Serveur", - "config.section_shares": "Partages publics", + "config.section_shares": "📤 Partages publics", "config.section_sidebar-barre-laterale": "Sidebar (barre latérale)", "config.section_synchronisation-automatique": "Synchronisation automatique", "config.section_tag-cloud": "Tag cloud", diff --git a/package.json b/package.json index 4b3de58..ed435e9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsigate", - "version": "2.12.1", + "version": "2.12.2", "description": "**Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive.", "main": "patch.js", "directories": { diff --git a/tests/frontend/unit.test.mjs b/tests/frontend/unit.test.mjs index 55e3f96..1d1e1a1 100644 --- a/tests/frontend/unit.test.mjs +++ b/tests/frontend/unit.test.mjs @@ -189,6 +189,38 @@ function testAdminModuleSyntax() { console.log(' ✓ admin.js parses without syntax errors'); } +// ── Test config TOC icons ───────────────────────────────────────────────── +const FRONTEND_DIR = join(__dirname, '../../frontend'); +const INDEX_HTML = join(FRONTEND_DIR, 'index.html'); +const ICON_RE = /^\p{Extended_Pictographic}/u; + +function testConfigTocIcons() { + const html = readFileSync(INDEX_HTML, 'utf-8'); + const keys = [ + ...html.matchAll( + / m[1]); + assert.ok(keys.length > 0, 'config TOC links found in index.html'); + + for (const lang of ['fr', 'en']) { + const locale = JSON.parse( + readFileSync(join(FRONTEND_DIR, 'locales', `${lang}.json`), 'utf-8'), + ); + for (const key of keys) { + const value = locale[key]; + assert.ok(value, `${lang}: missing TOC label for ${key}`); + assert.ok( + ICON_RE.test(value), + `${lang}: TOC label for ${key} has no icon ("${value}")`, + ); + } + } + console.log( + ` ✓ config TOC labels (${keys.length}) all carry an icon in FR and EN`, + ); +} + // ── Test ai-fab.js (FAB — Floating Action Button) ───────────────────────── const AIFAB_PATH = join(JS_DIR, 'ai-fab.js'); @@ -222,6 +254,7 @@ async function main() { ['admin module syntax', testAdminModuleSyntax], ['ai-fab module exists', testAIFabModuleExists], ['ai-fab module exports', testAIFabModuleExports], + ['config TOC icons', testConfigTocIcons], ]; for (const [name, fn] of tests) {