fix(ai): selection visible des menus et retrait de l'indice clavier (BUG-015)
CI / lint (push) Successful in 1m14s
CI / security (push) Successful in 44s
CI / test (push) Successful in 3m0s
CI / build (push) Successful in 1m3s
CI / e2e (push) Successful in 10m38s

BUG-015: l'etat actif des menus / et @ (et de la liste de modeles) utilise --bg-hover + barre d'accent a gauche, car --surface2 est identique a --bg-primary en theme sombre. Retrait de l'indice 'Entree pour envoyer...' sous la zone de saisie.
This commit is contained in:
2026-09-12 19:00:05 -04:00
parent a5201a62e0
commit d6cdd670b1
6 changed files with 23 additions and 5 deletions
+9 -1
View File
@@ -227,7 +227,8 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
« Fournisseur & modèle » perd ses intitulés (titre de section et libellé « Fournisseur : ») « Fournisseur & modèle » perd ses intitulés (titre de section et libellé « Fournisseur : »)
pour rester discrète ; la description du contexte Général n'est plus affichée (bandeau de pour rester discrète ; la description du contexte Général n'est plus affichée (bandeau de
statut masqué, description accessible au **survol** de l'en-tête) ; le placeholder statut masqué, description accessible au **survol** de l'en-tête) ; le placeholder
« Posez une question sur ces documents… » est retiré ; le bouton « Envoyer » devient un **emoji « Posez une question sur ces documents… » est retiré ; l'indice clavier
« Entrée pour envoyer · Ctrl+Entrée… » est retiré ; le bouton « Envoyer » devient un **emoji
compact** (✈️). Un **indicateur d'activité** apparaît pendant le traitement et détaille le compact** (✈️). Un **indicateur d'activité** apparaît pendant le traitement et détaille le
workflow : envoi, réception de la réponse, appels d'outils (`Outil : X…`), attente de workflow : envoi, réception de la réponse, appels d'outils (`Outil : X…`), attente de
confirmation, succès ou échec. i18n FR/EN (`ai.activity_*`, `ai.composer_label`). Tests JSDOM confirmation, succès ou échec. i18n FR/EN (`ai.activity_*`, `ai.composer_label`). Tests JSDOM
@@ -235,6 +236,13 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### Corrigé ### Corrigé
- **BUG-015 — Assistant IA : sélection des menus `/` et `@` invisible au clavier** — l'élément
actif utilisait `background: var(--surface2)`, or `--surface2` est **identique** à
`--bg-primary` (fond du menu) dans le thème sombre par défaut : la ligne sélectionnée par les
flèches ↑/↓ ne se distinguait pas. L'état actif (et le survol) utilise désormais
`--bg-hover` avec une **barre d'accent** à gauche (`box-shadow: inset 3px 0 0 var(--accent)`),
pour les menus de commandes/mentions **et** la liste de modèles. Test JSDOM mis à jour.
- **BUG-014 — Assistant IA : navigation clavier ↑/↓ des menus inopérante** — la navigation était - **BUG-014 — Assistant IA : navigation clavier ↑/↓ des menus inopérante** — la navigation était
liée au `keydown` du champ de saisie : dès que le focus quittait la zone de texte (clic sur le liée au `keydown` du champ de saisie : dès que le focus quittait la zone de texte (clic sur le
menu, bouton Envoyer…), les flèches ne faisaient plus défiler les items. La gestion est déplacée menu, bouton Envoyer…), les flèches ne faisaient plus défiler les items. La gestion est déplacée
+2
View File
@@ -124,6 +124,7 @@ Avant de corriger quoi que ce soit, un agent IA doit :
| *BUG-012* | Assistant IA : la commande `@` n'affiche aucun menu de sélection en mode Général | 🟢 corrigé | P1 | 📱 frontend | IA | `frontend/js/bookslm.js` | Assistant en mode Général (aucun vault), taper `@` | `_showMentionMenu` rend **toujours** le menu (même vide) et `_activeVault()` retombe sur `state.selectedContextVault` puis le premier `state.allVaults`, avant `vault=all` pour les requêtes | Sans vault résolu, l'ancien code masquait le menu et le backend ignorait le contexte. Tests : `tests/frontend/ai.test.mjs` (+1) | | *BUG-012* | Assistant IA : la commande `@` n'affiche aucun menu de sélection en mode Général | 🟢 corrigé | P1 | 📱 frontend | IA | `frontend/js/bookslm.js` | Assistant en mode Général (aucun vault), taper `@` | `_showMentionMenu` rend **toujours** le menu (même vide) et `_activeVault()` retombe sur `state.selectedContextVault` puis le premier `state.allVaults`, avant `vault=all` pour les requêtes | Sans vault résolu, l'ancien code masquait le menu et le backend ignorait le contexte. Tests : `tests/frontend/ai.test.mjs` (+1) |
| *BUG-013* | Assistant IA : les liens fichiers/répertoires des réponses affichent « Aucun vault actif pour ouvrir ce lien » | 🟢 corrigé | P1 | 📱 frontend | IA | `frontend/js/bookslm.js` | En mode Général, cliquer un lien de fichier/dossier dans une réponse | `_openFileLink()` et `_revealPath()` utilisent `_activeVault()` (vault de contexte → vault sélectionné → premier vault) au lieu de `_resolveVault()` seul | `_resolveVault()` est nul sans document ouvert ; les liens échouaient en mode Général. Tests : `tests/frontend/ai.test.mjs` (+1) | | *BUG-013* | Assistant IA : les liens fichiers/répertoires des réponses affichent « Aucun vault actif pour ouvrir ce lien » | 🟢 corrigé | P1 | 📱 frontend | IA | `frontend/js/bookslm.js` | En mode Général, cliquer un lien de fichier/dossier dans une réponse | `_openFileLink()` et `_revealPath()` utilisent `_activeVault()` (vault de contexte → vault sélectionné → premier vault) au lieu de `_resolveVault()` seul | `_resolveVault()` est nul sans document ouvert ; les liens échouaient en mode Général. Tests : `tests/frontend/ai.test.mjs` (+1) |
| *BUG-014* | Assistant IA : les flèches ↑/↓ ne naviguent pas dans les menus `/` et `@` | 🟢 corrigé | P1 | 📱 frontend | IA | `frontend/js/bookslm.js` | Ouvrir `/`, puis ↑/↓ (y compris après un clic hors zone de texte) | Navigation gérée au niveau du **panneau en phase de capture** (`panel.addEventListener('keydown', ..., true)`), donc indépendante du focus | Le `keydown` n'était écouté que sur la zone de texte ; dès que le focus changeait, les flèches étaient ignorées. Tests : `tests/frontend/ai.test.mjs` (+1) | | *BUG-014* | Assistant IA : les flèches ↑/↓ ne naviguent pas dans les menus `/` et `@` | 🟢 corrigé | P1 | 📱 frontend | IA | `frontend/js/bookslm.js` | Ouvrir `/`, puis ↑/↓ (y compris après un clic hors zone de texte) | Navigation gérée au niveau du **panneau en phase de capture** (`panel.addEventListener('keydown', ..., true)`), donc indépendante du focus | Le `keydown` n'était écouté que sur la zone de texte ; dès que le focus changeait, les flèches étaient ignorées. Tests : `tests/frontend/ai.test.mjs` (+1) |
| *BUG-015* | Assistant IA : la ligne sélectionnée des menus `/` et `@` est invisible au clavier | 🟢 corrigé | P2 | 📱 frontend | IA | `frontend/style.css` | Ouvrir `/` ou `@`, naviguer avec ↑/↓ | État `.active` en `--bg-hover` + barre d'accent à gauche (`inset 3px 0 0 var(--accent)`) au lieu de `--surface2` | `--surface2` est identique à `--bg-primary` (fond du menu) en thème sombre : la sélection ne se voyait pas. Idem pour la liste de modèles |
### TODOs techniques (améliorations / nouvelles tâches) ### TODOs techniques (améliorations / nouvelles tâches)
@@ -152,6 +153,7 @@ Avant de corriger quoi que ce soit, un agent IA doit :
| 2026-09-12 | BUG-010, BUG-011 | Correction | `frontend/js/bookslm.js`, `frontend/js/ai.js`, `frontend/style.css`, `tests/frontend/ai.test.mjs` | BUG-010 : capture du `vault` des résultats `@` + `_contextVault()` propagé aux requêtes `/context`/`/chat` (mode Général). BUG-011 : popover modèle aligné à droite, largeur 340 px, noms multi-lignes + `title`. Vérifié en navigateur (Playwright) et tests frontend 43/43. | 🟢 corrigé (en attente vérif utilisateur) | | 2026-09-12 | BUG-010, BUG-011 | Correction | `frontend/js/bookslm.js`, `frontend/js/ai.js`, `frontend/style.css`, `tests/frontend/ai.test.mjs` | BUG-010 : capture du `vault` des résultats `@` + `_contextVault()` propagé aux requêtes `/context`/`/chat` (mode Général). BUG-011 : popover modèle aligné à droite, largeur 340 px, noms multi-lignes + `title`. Vérifié en navigateur (Playwright) et tests frontend 43/43. | 🟢 corrigé (en attente vérif utilisateur) |
| 2026-09-12 | BUG-012, #82 | Correction + UX | `frontend/js/bookslm.js`, `frontend/js/ai.js`, `frontend/style.css`, `frontend/sw.js`, `frontend/locales/{fr,en}.json`, `tests/frontend/ai.test.mjs` | BUG-012 : le menu `@` est toujours rendu et `_mentionVault()` retombe sur le vault de contexte puis le premier vault disponible. #82 : suppression des intitulés « Fournisseur & modèle » / « Fournisseur : », description du contexte Général déplacée en info-bulle, placeholder retiré, bouton Envoyer en emoji ✈️, indicateur d'activité (envoi/réception/outils/confirmation/succès/échec), `SW_VERSION` v5. Vérifié Playwright + tests frontend 45/45. | 🟢 corrigé (en attente vérif utilisateur) | | 2026-09-12 | BUG-012, #82 | Correction + UX | `frontend/js/bookslm.js`, `frontend/js/ai.js`, `frontend/style.css`, `frontend/sw.js`, `frontend/locales/{fr,en}.json`, `tests/frontend/ai.test.mjs` | BUG-012 : le menu `@` est toujours rendu et `_mentionVault()` retombe sur le vault de contexte puis le premier vault disponible. #82 : suppression des intitulés « Fournisseur & modèle » / « Fournisseur : », description du contexte Général déplacée en info-bulle, placeholder retiré, bouton Envoyer en emoji ✈️, indicateur d'activité (envoi/réception/outils/confirmation/succès/échec), `SW_VERSION` v5. Vérifié Playwright + tests frontend 45/45. | 🟢 corrigé (en attente vérif utilisateur) |
| 2026-09-12 | BUG-013, BUG-014 | Correction | `frontend/js/bookslm.js`, `frontend/index.html`, `frontend/sw.js`, `tests/frontend/ai.test.mjs` | BUG-013 : liens fichiers/dossiers via `_activeVault()` (vault de contexte → sélection → premier vault). BUG-014 : navigation ↑/↓ gérée au niveau du panneau en phase de capture. Purge des caches élargie (`SW_VERSION` v6, migration `obsigate-*`). Vérifié : tests frontend 47/47, pytest 930. | 🟢 corrigé (en attente vérif utilisateur) | | 2026-09-12 | BUG-013, BUG-014 | Correction | `frontend/js/bookslm.js`, `frontend/index.html`, `frontend/sw.js`, `tests/frontend/ai.test.mjs` | BUG-013 : liens fichiers/dossiers via `_activeVault()` (vault de contexte → sélection → premier vault). BUG-014 : navigation ↑/↓ gérée au niveau du panneau en phase de capture. Purge des caches élargie (`SW_VERSION` v6, migration `obsigate-*`). Vérifié : tests frontend 47/47, pytest 930. | 🟢 corrigé (en attente vérif utilisateur) |
| 2026-09-12 | BUG-015, #82 | Correction + UX | `frontend/js/bookslm.js`, `frontend/style.css`, `tests/frontend/ai.test.mjs` | BUG-015 : sélection des menus `/` et `@` rendue visible (`--bg-hover` + barre d'accent à gauche) car `--surface2` = `--bg-primary`. #82 : retrait de l'indice clavier sous la zone de saisie. Vérifié Playwright (contraste `#1f2430` vs `#0f1117` + barre accent) et tests frontend 47/47. | 🟢 corrigé (en attente vérif utilisateur) |
--- ---
+4
View File
@@ -71,6 +71,10 @@
Général (BUG-013). Général (BUG-013).
- [x] Purge des caches élargie : `SW_VERSION` v6 + migration qui supprime tous les caches - [x] Purge des caches élargie : `SW_VERSION` v6 + migration qui supprime tous les caches
`obsigate-*` (clé `obsigate-sw-migration` → `v3`). `obsigate-*` (clé `obsigate-sw-migration` → `v3`).
- [x] Indice clavier sous la zone de saisie retiré pour un composeur plus épuré (#82).
- [x] Sélection clavier des menus `/` et `@` rendue visible : état actif en `--bg-hover` +
barre d'accent à gauche (`--surface2` étant identique à `--bg-primary` en thème sombre,
la sélection était invisible) — BUG-015.
## H. Points d'attention ## H. Points d'attention
- La table de capacités reste **statique** (`backend/model_capabilities.py`) : un modèle inconnu - La table de capacités reste **statique** (`backend/model_capabilities.py`) : un modèle inconnu
-1
View File
@@ -506,7 +506,6 @@ class BooksLM {
<textarea placeholder="${t('bookslm.placeholder')}" rows="1" aria-label="${t('ai.composer_label')}"></textarea> <textarea placeholder="${t('bookslm.placeholder')}" rows="1" aria-label="${t('ai.composer_label')}"></textarea>
<button class="bookslm-btn-send" title="${t('bookslm.send')}" aria-label="${t('bookslm.send')}">✈️</button> <button class="bookslm-btn-send" title="${t('bookslm.send')}" aria-label="${t('bookslm.send')}">✈️</button>
</div> </div>
<div class="bookslm-input-hint">${t('ai.input_hint')}</div>
`; `;
// Provider/model picker lives on its own toolbar row so the header // Provider/model picker lives on its own toolbar row so the header
+7 -2
View File
@@ -9348,7 +9348,11 @@ body.bookslm-resizing { cursor: ew-resize; user-select: none; }
.bookslm-menu-item { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; .bookslm-menu-item { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
background: none; border: none; cursor: pointer; padding: 7px 9px; border-radius: 7px; background: none; border: none; cursor: pointer; padding: 7px 9px; border-radius: 7px;
color: var(--text-primary); font-size: 13px; } color: var(--text-primary); font-size: 13px; }
.bookslm-menu-item:hover, .bookslm-menu-item.active { background: var(--surface2); } .bookslm-menu-item:hover { background: var(--bg-hover); }
/* The active (keyboard) item needs a clearly visible highlight: --surface2 is
identical to --bg-primary in the default dark theme, so it was invisible. */
.bookslm-menu-item.active { background: var(--bg-hover); color: var(--text-primary);
box-shadow: inset 3px 0 0 var(--accent); }
.bookslm-menu-icon { flex-shrink: 0; } .bookslm-menu-icon { flex-shrink: 0; }
.bookslm-menu-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .bookslm-menu-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bookslm-menu-desc, .bookslm-menu-usage { margin-left: auto; font-size: 11px; color: var(--text-secondary); .bookslm-menu-desc, .bookslm-menu-usage { margin-left: auto; font-size: 11px; color: var(--text-secondary);
@@ -9402,7 +9406,8 @@ body.bookslm-resizing { cursor: ew-resize; user-select: none; }
.ai-picker-model-option { display: block; width: 100%; text-align: left; font-size: 0.78rem; .ai-picker-model-option { display: block; width: 100%; text-align: left; font-size: 0.78rem;
line-height: 1.3; padding: 5px 8px; border-radius: 5px; background: none; border: none; line-height: 1.3; padding: 5px 8px; border-radius: 5px; background: none; border: none;
color: var(--text-primary); cursor: pointer; white-space: normal; overflow-wrap: anywhere; } color: var(--text-primary); cursor: pointer; white-space: normal; overflow-wrap: anywhere; }
.ai-picker-model-option:hover, .ai-picker-model-option.active { background: var(--surface2); } .ai-picker-model-option:hover { background: var(--bg-hover); }
.ai-picker-model-option.active { background: var(--bg-hover); box-shadow: inset 3px 0 0 var(--accent); }
.ai-picker-model-empty { font-size: 0.7rem; color: var(--text-secondary); padding: 6px 8px; text-align: center; } .ai-picker-model-empty { font-size: 0.7rem; color: var(--text-secondary); padding: 6px 8px; text-align: center; }
.ai-picker-model-more { font-size: 0.7rem; color: var(--text-secondary); padding: 6px 8px; text-align: center; } .ai-picker-model-more { font-size: 0.7rem; color: var(--text-secondary); padding: 6px 8px; text-align: center; }
/* Capability info button (ⓘ) + informational bubble. */ /* Capability info button (ⓘ) + informational bubble. */
+1 -1
View File
@@ -360,7 +360,7 @@ async function main() {
assert.ok(actions.querySelector(".bookslm-btn-history"), "session history button"); assert.ok(actions.querySelector(".bookslm-btn-history"), "session history button");
assert.ok(panel.querySelector(".bookslm-history-menu"), "session history menu host"); assert.ok(panel.querySelector(".bookslm-history-menu"), "session history menu host");
assert.ok(panel.querySelector(".bookslm-toolbar .bookslm-picker-host"), "picker on its own toolbar row"); assert.ok(panel.querySelector(".bookslm-toolbar .bookslm-picker-host"), "picker on its own toolbar row");
assert.ok(panel.querySelector(".bookslm-input-hint"), "keyboard hint shown"); assert.ok(!panel.querySelector(".bookslm-input-hint"), "keyboard hint removed for a cleaner composer");
panel.remove(); panel.remove();
}); });