diff --git a/CHANGELOG.md b/CHANGELOG.md index ad63555..2aaa94e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,53 @@ # Changelog - FlowDeck +## v7.69.0 (2026-10-08) — La sélection multi-blocs fonctionne enfin (+ identité visuelle) + +### Fixed + +- **Ctrl+C / Ctrl+X multi-blocs ne faisaient RIEN** — cause racine : le navigateur + ne sait pas sérialiser une sélection qui traverse deux `contenteditable` (chaque + bloc en a un). Résultat : `getSelection().toString()` renvoie `""` et Chromium + **n'émet aucun événement `copy`** — nos handlers `ct.addEventListener('copy')` + n'étaient donc jamais atteints, et le raccourci mourait en silence. + → le raccourci est maintenant intercepté au `keydown` (capture sur `document`, + garde `closest('#_blocksCt')` pour ne pas voler Ctrl+C ailleurs) : on écrit le + markdown dans le presse-papier nous-mêmes. La sélection mono-bloc reste native. + - `Ctrl+X` supprime les blocs traversés en conservant la tête du premier et la + queue du dernier. +- **Glisser la souris d'un bloc à l'autre sélectionnait un seul bloc** — cause + racine : la séquence complète est `mouseup` (on reconstruit la plage) → `click` + → `focusin` → **le navigateur efface la sélection**. La plage était donc + reconstruite puis détruite dans la foulée. → la plage reconstruite est mise en + attente (`_mdSelRange`) et restaurée au tour de boucle suivant, si le focus + l'a effectivement effacée. Un nouveau geste (mousedown) remet l'attente à zéro, + donc un clic pour placer le curseur reste normal. +- **Le clic droit effaçait le surlignage** — la recherche du menu prenait le + focus 10 ms après son ouverture, ce qui détruisait la sélection. → on ne vole + plus le focus quand un texte est sélectionné. (Les actions Clipboard utilisaient + déjà la sélection figée à l'ouverture du menu : `d._clipSt`.) +- Le `preventDefault` du clic droit est bien sur `mousedown` (sur `contextmenu` + il arrive trop tard — le curseur a déjà déplacé la sélection). + +### Added + +- **Identité visuelle** : la bannière et le logo du projet sont intégrés. + - assets optimisés : `static/img/banner.webp` **22,5 Ko** (l'original fait + 1,6 Mo) + `banner.jpg` de secours, `logo.webp` **5,3 Ko** + `logo-512.jpg` ; + originaux conservés dans `assets/` pour régénération. + - icônes PWA régénérées à partir du vrai logo (72 → 512 px, marge maskable + sur 192/512) + `apple-touch-icon`. + - landing : logo dans la barre de navigation, bannière en `` + (WebP + JPEG) avec dimensions déclarées pour éviter tout décalage de mise en + page ; `og:image`, `twitter:card` et `meta description` ajoutés au ``. + +### Tests + +- `tests/test_v769_selection_persistence.py` (19 tests statiques) + + `e2e/v769_selection_persistence.spec.js` (5 tests, **vrais gestes** : glisser + de souris, `Ctrl+C`/`Ctrl+X` au clavier, clic droit). +- `e2e/v768_columns_clipboard.spec.js` : les gestes simulés (`execCommand`, + plage fabriquée en `evaluate`) sont remplacés par de vrais gestes. + ## v7.68.0 (2026-10-08) — Colonnes rendues, tables IA, copier/couper/coller multi-blocs ### Fixed diff --git a/ROADMAP.md b/ROADMAP.md index eee1a48..c90838e 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1545,6 +1545,42 @@ Détails livrés : `v768_columns_clipboard.spec.js` (4) ; `pytest` **1394 passed / 0 failed**, `ruff` OK ; `VERSION` + `app/main.py` = 7.68.0 +### v7.69.0 — La sélection multi-blocs fonctionne enfin ✅ (2026-10-08) + +**Contexte** : v7.68.0 livrait la mécanique Clipboard (plage multi-blocs, handlers +`copy`/`cut`, groupe Clipboard du menu contextuel) mais elle était **inutilisable en +pratique** — trois rapports d'usage : Ctrl+C ne copie rien, le glisser souris ne +sélectionne qu'un bloc, le clic droit efface le surlignage. + +**Causes racines trouvées (trace d'événements à l'appui, pas de supposition)** : + +| Symptôme | Cause réelle | +|----------|--------------| +| Ctrl+C/X muet | le navigateur **n'émet aucun événement `copy`** quand la sélection traverse deux `contenteditable` : `getSelection().toString()` renvoie `""`, donc nos handlers n'étaient jamais atteints | +| Glisser = 1 bloc | séquence `mouseup` → `click` → `focusin` → **collapse** : la plage reconstruite mourait dans la foulée | +| Clic droit efface | `.bm-search` prenait le focus 10 ms après l'ouverture du menu | + +**Corrections** : interception du raccourci au `keydown` (capture `document`, +garde `closest('#_blocksCt')`) ; plage reconstruite mise en attente +(`_mdSelRange`) et restaurée au tour suivant, remise à zéro à chaque nouveau +geste ; le menu ne vole plus le focus quand un texte est sélectionné ; +`preventDefault` du clic droit remonté sur `mousedown` (sur `contextmenu` c'est +trop tard). + +**Identité visuelle** : bannière + logo intégrés — WebP 22,5 Ko / 5,3 Ko (les +originaux faisaient 1,6 Mo / 1,1 Mo), JPEG de secours, icônes PWA régénérées à +partir du vrai logo, `` sur la landing, `og:image`/`twitter:card`. + +**Vérification** : `tests/test_v769_selection_persistence.py` (19 statiques) + +`e2e/v769_selection_persistence.spec.js` (5, **vrais gestes**) ; le spec v768 a +été corrigé pour remplacer `execCommand` et les plages fabriquées par de vrais +gestes. + +**Piège de test relevé au passage** : les `···` dans les échecs Playwright sont +le marqueur de troncature du message d'erreur, **pas** un bug produit — une heure +passée à chercher une fuite inexistante. Vérifier `JSON.stringify()` de la valeur +réelle avant de croire un affichage tronqué. + --- ## ✅ Fonctionnalités livrées hors roadmap (bonus détectés dans le code) diff --git a/VERSION b/VERSION index 97e05c6..0f4b2e9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.68.0 +7.69.0 diff --git a/WORKLOAD.md b/WORKLOAD.md index c50b139..312aab8 100644 --- a/WORKLOAD.md +++ b/WORKLOAD.md @@ -1,6 +1,6 @@ # WORKLOAD — FlowDeck Notion Clone -> **Début**: 2026-07-08 | **Version**: v7.68.0 (colonnes rendues, tables IA sans pipe de tête, copier/couper/coller multi-blocs) | **Statut**: EN COURS 🔄 +> **Début**: 2026-07-08 | **Version**: v7.69.0 (sélection multi-blocs fonctionnelle : drag souris + Maj+↓, clic droit qui la préserve) | **Statut**: EN COURS 🔄 > **Cible**: parité Notion + intégration forge · **Follow-ups v7.3 livrés**: sidebar teamspaces, notif `page.updated`, charts `number` + dashboards multi-DB, unfurl forge, UI Settings → Audit — voir `ROADMAP.md § v7.3.0` ## Avancement Global diff --git a/app/main.py b/app/main.py index 36a1de1..64ca72a 100644 --- a/app/main.py +++ b/app/main.py @@ -186,7 +186,7 @@ async def lifespan(_app: FastAPI): app = FastAPI( title="FlowDeck", - version="7.68.0", + version="7.69.0", docs_url="/docs", redoc_url="/redoc", lifespan=lifespan, diff --git a/app/templates/base.html b/app/templates/base.html index d8dcc87..67fc00a 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -8,6 +8,17 @@ + + + + + + + + + + + diff --git a/app/templates/landing.html b/app/templates/landing.html index cfe2b17..04a26e1 100644 --- a/app/templates/landing.html +++ b/app/templates/landing.html @@ -11,6 +11,17 @@ + + + + + + + + + + +