From 6f4363bde61bfca3a5e9b0334948c250ddb5f4d8 Mon Sep 17 00:00:00 2001 From: r-zakarya <82443831+r-zakarya@users.noreply.github.com> Date: Thu, 23 Jul 2026 15:59:53 +0100 Subject: [PATCH] fix(batch): move the selection bar into the title row MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Selecting an entry inserted the batch bar as a block above the grid, pushing every row down ~60px — the list jumped under the cursor mid-click. The bar now renders inside .content-header, to the right of "All items", and the header reserves its height (min-height) so appearing and disappearing shifts nothing at all. Co-Authored-By: Claude Opus 4.8 --- TEST_SCENARIOS.md | 12 ++++++------ css/style.css | 15 +++++++++------ js/app.js | 3 +-- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/TEST_SCENARIOS.md b/TEST_SCENARIOS.md index 45f0b4f..820cc00 100644 --- a/TEST_SCENARIOS.md +++ b/TEST_SCENARIOS.md @@ -25,27 +25,27 @@ Convention : **PRÉ** = état de départ, **ACTION**, **ATTENDU**. Un test qui Préparer : 3 entrées `A`, `B`, `C`, dont `A` dans le dossier `Work` avec le tag `old`. -### A1 · batch Add tag sur l'entrée éditée +### A1 · batch Add tag sur l'entrée éditée - **PRÉ** : `A` ouverte dans l'éditeur, taper du texte dans NOTE/PASSWORD (ne pas sauver) - **ACTION** : cocher `A` + `B` → barre de sélection → *Add tag* → `shared` → puis **Save** dans l'éditeur -- **ATTENDU** : le chip `shared` apparaît **immédiatement** dans l'éditeur ; après Save, `A` porte `old, shared` **et** la modif tapée. Le bouton Save reste visible (l'entrée était déjà dirty) mais le tag seul ne rend pas dirty. +- **ATTENDU** : le chip `shared` apparaît **immédiatement** dans l'éditeur ; après Save, `A` porte `old, shared` **et** la modif tapée. Le bouton Save reste visible (l'entrée était déjà dirty) mais le tag seul ne rend pas dirty.✅ ### A2 · batch Add tag sur une **autre** entrée - **PRÉ** : `A` ouverte + dirty - **ACTION** : cocher `B` + `C` seulement → *Add tag* → `x` → Save dans l'éditeur -- **ATTENDU** : l'éditeur ne bouge pas (aucun chip ajouté), `A` conserve ses tags, `B`/`C` taguées. +- **ATTENDU** : l'éditeur ne bouge pas (aucun chip ajouté), `A` conserve ses tags, `B`/`C` taguées.✅ ### A3 · batch Move to folder sur l'entrée éditée - **ACTION** : `A` ouverte + dirty → cocher `A` → *Move to folder…* → `Perso` → Save -- **ATTENDU** : le select Folder de l'éditeur bascule sur `Perso` tout seul ; après Save l'entrée est bien dans `Perso`. +- **ATTENDU** : le select Folder de l'éditeur bascule sur `Perso` tout seul ; après Save l'entrée est bien dans `Perso`.✅ ### A4 · dossier choisi dans l'éditeur **puis** move extérieur - **ACTION** : `A` ouverte, changer Folder → `Archive` (ne pas sauver) → cocher `A` → *Move to folder…* → `Perso` → Save -- **ATTENDU** : `Perso` gagne (action extérieure = intention la plus récente). Comportement documenté, pas un bug. +- **ATTENDU** : `Perso` gagne (action extérieure = intention la plus récente). Comportement documenté, pas un bug. ✅ ### A5 · glisser une entrée sur un dossier (`moveEntryToFolder`) - **ACTION** : `A` ouverte + dirty → glisser la ligne `A` sur `Perso` dans la sidebar → Save -- **ATTENDU** : identique à A3. +- **ATTENDU** : identique à A3.✅ ### A6 · glisser une **multi-sélection** sur un dossier (`moveEntriesToFolder`) ⚠️ - **ACTION** : cocher `A` + `B` → glisser sur `Perso` → recharger (F5 impossible : relancer l'app) diff --git a/css/style.css b/css/style.css index 12e7d37..8146348 100644 --- a/css/style.css +++ b/css/style.css @@ -807,6 +807,8 @@ input[type="range"]::-webkit-slider-thumb { table header) offsets by --hdr-h. */ .content-header { display: flex; align-items: baseline; gap: 12px; margin-bottom: 20px; + /* Height of the batch bar — reserved even when nothing is selected. */ + min-height: 38px; position: sticky; top: 0; z-index: 12; background: var(--bg); padding-top: 24px; @@ -1008,14 +1010,15 @@ input[type="range"]::-webkit-slider-thumb { font-size: 11px; } -/* Batch action bar (appears when selection is non-empty) */ +/* Batch action bar (appears when selection is non-empty). It lives INSIDE + .content-header, to the right of the title: as a block of its own it pushed + the whole list down on every selection. The header reserves its height (see + .content-header min-height) so appearing/disappearing shifts nothing. */ .batch-bar { - position: sticky; - top: var(--hdr-h, 0px); - z-index: 10; + flex: 1; + align-self: center; display: flex; align-items: center; gap: 8px; - padding: 10px 14px; - margin-bottom: 16px; + padding: 5px 10px; background: var(--bg-elev); border: 1px solid var(--accent); border-radius: var(--radius); diff --git a/js/app.js b/js/app.js index bea1656..9a2a69a 100644 --- a/js/app.js +++ b/js/app.js @@ -3708,8 +3708,7 @@ function renderBatchBar() { on: { click: clearChecked }, }, withIcon('i-x', 'Clear'))); - const content = $('.content'); - content.insertBefore(bar, $('#entryGrid')); + $('.content-header').appendChild(bar); } // ============================================================