feat(assistant): #91 fenêtre de résultats — post épinglé en haut, fournisseur/modèle discret & bouton copier
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
# #91 — Assistant IA — Fenêtre de résultats : post en haut, fournisseur/modèle & bouton copier
|
||||
|
||||
> **Statut :** ✅ Livré
|
||||
> **Effort :** 0,5-1 jour | **Impact :** 🟡
|
||||
> **Références :** [Roadmap](../ROADMAP.md) · [BooksLM #76](./bookslm.md) · [Assistant UX #80](./ai-assistant-ux.md) · [Changelog](../../CHANGELOG.md)
|
||||
|
||||
- **Description :** Trois améliorations d'expérience dans la fenêtre de résultats de
|
||||
l'assistant IA (`frontend/js/bookslm.js`, `frontend/style.css`) :
|
||||
1. **Post toujours en haut** : dès qu'un message est soumis, ce tour (le post
|
||||
utilisateur **et** la réponse de l'assistant en cours d'écriture) est épinglé en
|
||||
haut de la fenêtre de messages, afin que le résultat écrit par l'assistant reste
|
||||
toujours visible — même après re-render successifs et auto-scroll.
|
||||
2. **Fournisseur & modèle discrets** : juste au-dessus du bloc de texte rédigé par
|
||||
l'assistant, un libellé discret rapporte le fournisseur et le modèle réellement
|
||||
utilisés (fournis par le backend via le flux SSE `{token, provider, model}`).
|
||||
3. **Bouton « Copier »** : sous le bloc soumis par l'utilisateur ainsi que sous le
|
||||
bloc rédigé par l'assistant, un bouton copie le texte brut de ce bloc dans le
|
||||
presse-papiers (avec toast de confirmation).
|
||||
|
||||
## A. Post toujours en haut — ✅ livré
|
||||
- [x] **A1.** Chaque message est enveloppé dans un bloc `.bookslm-msg` ; le conteneur
|
||||
`.bookslm-messages` est un flex column et les blocs du **dernier tour** (depuis le
|
||||
dernier message utilisateur inclus) portent `.latest` → `order: -1`, les épinglant
|
||||
en haut de la fenêtre.
|
||||
- [x] **A2.** La détection du dernier tour se fait au rendu (`_renderMessages()`) en
|
||||
recherchant le dernier message `role === 'user'` ; tout ce qui suit (sa réponse, ses
|
||||
actions/cartes) reste groupé au-dessus de l'historique antérieur.
|
||||
- [x] **A3.** L'auto-scroll vers le bas (`scrollTop = scrollHeight`) conserve le dernier
|
||||
tour en haut, hors d'atteinte du contenu précédent.
|
||||
|
||||
## B. Fournisseur & modèle discrets — ✅ livré
|
||||
- [x] **B1.** `_streamResponse()` capture `data.provider` et `data.model` du flux SSE
|
||||
(déjà émis par `/chat` et `/agent`) sur le message assistant.
|
||||
- [x] **B2.** Au rendu d'un message assistant, `.bookslm-msg-meta` affiche
|
||||
« `fournisseur · modèle` » au-dessus du bloc (visible uniquement si l'info est reçue).
|
||||
- [x] **B3.** Style discret (10px, `var(--text-secondary)`), non sélectionnable.
|
||||
|
||||
## C. Bouton « Copier » — ✅ livré
|
||||
- [x] **C1.** `_appendCopyButton()` ajoute un bouton `.bookslm-copy-btn` sous chaque
|
||||
bloc non vide (utilisateur et assistant) avec le texte i18n `bookslm.copy`.
|
||||
- [x] **C2.** `_copyText()` copie le **texte brut** du message (`navigator.clipboard`,
|
||||
repli `_fallbackCopy`) et affiche le toast `bookslm.copied`.
|
||||
- [x] **C3.** Le bouton est masqué par défaut (opacité 0) et révélé au survol du bloc
|
||||
`.bookslm-msg`.
|
||||
|
||||
## D. Tests & documentation — ✅ livré
|
||||
- [x] **D1.** `tests/frontend/ai.test.mjs` : dernier tour épinglé, tag fournisseur/modèle
|
||||
rendu, boutons copier présents sur les deux blocs, copie du texte brut, absence de
|
||||
bouton pour un contenu vide.
|
||||
- [x] **D2.** i18n FR/EN : `bookslm.copied`.
|
||||
- [x] **D3.** CHANGELOG + Roadmap.
|
||||
|
||||
## E. Points d'attention
|
||||
- Le tag provient du **backend réel** (`provider`/`model` du SSE) et reflète donc le
|
||||
modèle effectif même lorsque l'utilisateur conserve la sélection « par défaut ».
|
||||
- Le copier utilise le texte brut (pas le HTML rendu) — cohérent avec l'export de
|
||||
conversation et évite d'embarquer des liens/balises de rendu.
|
||||
Reference in New Issue
Block a user