feat: editor improvements and architectural grid prototype
Multiple feature additions and improvements across the application: - NextGen Editor: drag handles, smart paste, block actions - Structured views: Kanban and table layouts for notes - Architectural Grid: new brainstorming/agent interface prototype - Flashcards: SM-2 revision algorithm with AI generation - MCP server: robustness improvements - Graph/PDF chat: fix click propagation and copy behavior - Various UI/UX enhancements and bug fixes Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# User Stories — Momento Next Phase
|
||||
|
||||
> Basé sur l'analyse du prototype `architectural-grid/` et du code production `memento-note/`.
|
||||
> Dernière mise à jour : 2026-05-24
|
||||
> Dernière mise à jour : 2026-05-25 (US-NEXTGEN-EDITOR réorganisé, 4 nouvelles stories éditeur ajoutées)
|
||||
|
||||
---
|
||||
|
||||
@@ -16,25 +16,44 @@
|
||||
| **US-INFO-RÉSEAU** | Panneau Info + Réseau Local | ✅ **LIVRÉ** | `note-network-tab.tsx`, `sync-note-links.ts`, migration `NoteLink`, picker `[[` |
|
||||
| **US-CLIPPER** | Web Clipper | ✅ **LIVRÉ** | `extension/`, `/api/clip/*`, migration `sourceUrl`, badge panneau Info |
|
||||
| **US-GRAPH** | Graphe de Connaissance Global enrichi | ✅ **LIVRÉ** | `note-graph-view.tsx` — filtres liens, seuil sémantique, focus voisinage, couleurs carnets, double-clic ouverture |
|
||||
| **US-INSIGHTS** | Clusters Sémantiques + Bridge Notes | 🚧 **EN COURS** | clusters en base mais page masquait les résultats périmés — correction affichage |
|
||||
| **US-TEMPORAL** | Prédictions d'accès temporelles | ⏳ À faire | — |
|
||||
| **US-INSIGHTS** | Clusters Sémantiques + Bridge Notes | ✅ **LIVRÉ** | `app/(main)/insights/page.tsx`, `network-graph.tsx`, `/api/clusters`, `/api/bridge-notes/*`, état dégradé si clusters périmés |
|
||||
| **US-TEMPORAL** | Prédictions d'accès temporelles | ⏸️ **REPORTÉ** | Remplacé par rappels + révision SM-2 + Memory Echo ; heuristique faible, migration NoteAccessLog non prioritaire |
|
||||
| **US-FLASHCARDS** | Révision IA — Répétition espacée SM-2 | ✅ **LIVRÉ** | `/revision`, `/api/flashcards/*`, SM-2, génération IA depuis l'éditeur |
|
||||
| **US-STRUCTURED-VIEWS** | Vues Structurées (Tableau/Kanban/Galerie) | ✅ **LIVRÉ** | `/api/notebooks/[id]/schema`, `/api/notes/[id]/properties`, vues structurées + panneau propriétés éditeur |
|
||||
| **US-NEXTGEN-EDITOR** | Éditeur Next-Gen : Drag Handle + Menu Bloc + DB Inline + Smart Paste | 🚧 **PLANIFIÉ** | Voir `docs/story-nextgen-editor.md` |
|
||||
| **US-EDITOR-PERF** | Performance de frappe TipTap (quick wins) | 🚧 **PLANIFIÉ** | — |
|
||||
| **US-EDITOR-UX** | Micro-interactions saisie (slash menu, sélection multi-blocs, paste étendu, placeholders) | ⏳ **À FAIRE** | — |
|
||||
| **US-EDITOR-MOBILE** | Expérience tactile & toolbar mobile adaptée | ⏳ **À FAIRE** | — |
|
||||
| **US-EDITOR-MARKDOWN** | Rendu WYSIWYG Markdown fidèle (round-trip byte-for-byte) | ⏳ **À FAIRE** | — |
|
||||
|
||||
---
|
||||
|
||||
## Ordre d'implémentation (dépendances)
|
||||
|
||||
```
|
||||
US-LIVING-BLOCKS ← dépend de : TipTap UniqueID (fondation)
|
||||
US-MEMORY-ECHO ← dépend de : pgvector existant (aucune migration)
|
||||
US-INFO-RÉSEAU ← dépend de : wikilinks + backlinks existants
|
||||
US-CLIPPER ← dépend de : migration Note.sourceUrl
|
||||
US-GRAPH ← dépend de : /api/graph existant
|
||||
US-INSIGHTS ← dépend de : Memory Echo + clusters
|
||||
US-TEMPORAL ← dépend de : migration NoteAccessLog
|
||||
US-FLASHCARDS ← dépend de : migration FlashcardDeck + Flashcard
|
||||
US-STRUCTURED-VIEWS ← dépend de : migration NotebookSchema + NotebookProperty
|
||||
Quick wins (en premier, ~2h) :
|
||||
US-EDITOR-PERF <- depend de : rien (modifs config TipTap)
|
||||
|
||||
Editeur Next-Gen (bloc principal) :
|
||||
US-NEXTGEN-EDITOR <- depend de : US-LIVING-BLOCKS, US-STRUCTURED-VIEWS
|
||||
US-EDITOR-UX <- depend de : US-NEXTGEN-EDITOR (drag handle + menu bloc en place)
|
||||
US-EDITOR-MOBILE <- depend de : US-NEXTGEN-EDITOR (drag handle existant)
|
||||
|
||||
Plus tard :
|
||||
US-EDITOR-MARKDOWN <- depend de : rien (evaluation Milkdown, low priority)
|
||||
|
||||
Stories livrees :
|
||||
US-LIVING-BLOCKS <- depend de : TipTap UniqueID (fondation)
|
||||
US-MEMORY-ECHO <- depend de : pgvector existant
|
||||
US-INFO-RESEAU <- depend de : wikilinks + backlinks
|
||||
US-CLIPPER <- depend de : migration Note.sourceUrl
|
||||
US-GRAPH <- depend de : /api/graph existant
|
||||
US-INSIGHTS <- depend de : Memory Echo + clusters
|
||||
US-FLASHCARDS <- depend de : migration FlashcardDeck + Flashcard
|
||||
US-STRUCTURED-VIEWS <- depend de : migration NotebookSchema + NotebookProperty
|
||||
|
||||
Reportees :
|
||||
US-TEMPORAL <- depend de : migration NoteAccessLog (REPORTE)
|
||||
```
|
||||
|
||||
---
|
||||
@@ -539,6 +558,8 @@ model FlashcardReview {
|
||||
|
||||
## US-TEMPORAL — Prédictions d'Accès Temporelles
|
||||
|
||||
> **Statut : ⏸️ REPORTÉ (2026-05-24)** — Chevauche rappels, révision SM-2 et Memory Echo ; faible signal sans volume d'ouvertures ; pas prioritaire pour éviter la surcharge produit. Spec conservée pour réévaluation ultérieure éventuelle.
|
||||
|
||||
**Contexte :**
|
||||
`TemporalView.tsx` (169L) prédit quelles notes l'utilisateur voudra relire, basé sur des patterns d'accès. Rien n'existe en prod. Feature légère à fort impact perçu.
|
||||
|
||||
@@ -569,3 +590,231 @@ model NoteAccessLog {
|
||||
- Liste des 3 meilleures prédictions
|
||||
- Badge `cyclique` / `tendance` selon le type
|
||||
- Clic → ouvre la note
|
||||
|
||||
---
|
||||
|
||||
## US-NEXTGEN-EDITOR — Éditeur Next-Gen : Drag Handle + Menu Bloc + DB Inline + Smart Paste
|
||||
|
||||
> **Status :** PLANIFIÉ
|
||||
> **Depends on :** US-LIVING-BLOCKS (UniqueID et transclusion), US-STRUCTURED-VIEWS (NotebookSchema et propriétés)
|
||||
> **Spec détaillée :** `docs/story-nextgen-editor.md` (4 sous-stories : US-1 Drag Handle, US-2 Menu Action Bloc, US-3 Smart Paste, US-4 Database Inline)
|
||||
|
||||
**Contexte :**
|
||||
L'éditeur actuel est un document linéaire classique. Pour rivaliser avec Notion tout en étant plus performant, on implémente une approche hybride : un unique bouton de poignée en ProseMirror pur (pas de composant React lourd par paragraphe), un menu contextuel de bloc, une transclusion au collage, et un bloc database inline.
|
||||
|
||||
**4 sous-stories** (détail dans `docs/story-nextgen-editor.md`) :
|
||||
|
||||
### US-1 : Poignée de Glissement Gutter Unique (Hover Drag Handle)
|
||||
- Bouton flottant unique dans la marge gauche, suit le curseur de bloc en bloc
|
||||
- Un seul élément DOM repositionné (pas de duplication)
|
||||
- Drag & drop de blocs avec indicateur de ligne d'insertion
|
||||
- Masqué sur mobile/tactile
|
||||
|
||||
### US-2 : Menu Action Rapide de Bloc
|
||||
- Clic sur la poignée -> dropdown glassmorphism
|
||||
- Actions : Supprimer, Dupliquer, Transformer en (H1/H2/H3/liste/todo/citation/code/database), Copier la référence
|
||||
- Utilise le `UniqueID` TipTap pour les références stables
|
||||
|
||||
### US-3 : Transclusion intelligente au Collage (Smart Paste)
|
||||
- Collage d'un lien de bloc -> menu inline : "Bloc Connecté (Live)" ou "Texte simple"
|
||||
- Insère un nœud `liveBlock` synchronisé via Redis Pub/Sub
|
||||
|
||||
### US-4 : Bloc de Base de Données Relationnelle Inline
|
||||
- Slash `/database` -> insère un React NodeView
|
||||
- Vues Tableau / Fiches avec Rollup dynamique
|
||||
- Modèle relationnel local (auteurs/livres par défaut, ou lié au carnet)
|
||||
|
||||
### Fichiers
|
||||
- `[NEW]` `tiptap-drag-handle-plugin.ts` — Plugin ProseMirror pur
|
||||
- `[NEW]` `tiptap-database-block-extension.tsx` — NodeView React
|
||||
- `[MODIFY]` `rich-text-editor.tsx` — Intégration drag handle + DB + paste intercept
|
||||
- `[MODIFY]` `globals.css` — Gutter, poignée, glassmorphic dropdowns
|
||||
|
||||
---
|
||||
|
||||
## US-EDITOR-PERF — Performance de Frappe TipTap (Quick Wins)
|
||||
|
||||
> **Status :** PLANIFIÉ
|
||||
> **Depends on :** rien (modifications config TipTap, ~2h)
|
||||
> **Priorité :** HAUTE — impact immédiat sur le ressenti de saisie
|
||||
> **Source recherche :** TipTap 2.5 (mai 2026), TipTap docs performance, PR #7828
|
||||
|
||||
**Contexte :**
|
||||
Actuellement `rich-text-editor.tsx` utilise `immediatelyRender: false` mais pas `shouldRerenderOnTransaction` ni `useEditorState`. TipTap re-render le composant React à chaque transaction (frappe, déplacement curseur, sélection) — ce qui ajoute de la latence. Obsidian atteint <16ms de latence (local-first), Notion 50-150ms (cloud). Momento est local mais se comporte comme Notion à cause de ces re-renders inutiles.
|
||||
|
||||
**En tant qu'utilisateur**, je veux que la frappe dans l'éditeur soit instantanée, sans aucun décalage perceptible, même sur des notes longues avec de nombreux blocs.
|
||||
|
||||
### 1. shouldRerenderOnTransaction: false (1 ligne)
|
||||
```typescript
|
||||
// rich-text-editor.tsx — useEditor()
|
||||
const editor = useEditor({
|
||||
extensions: [...],
|
||||
immediatelyRender: false,
|
||||
shouldRerenderOnTransaction: false, // <-- AJOUTER
|
||||
// ...
|
||||
})
|
||||
```
|
||||
- Le composant React EditorContent ne se re-render plus sur chaque transaction
|
||||
- Seul le DOM ProseMirror est mis à jour (ultra-rapide, natif)
|
||||
- Gain mesurable : de ~50-100ms par frappe à <16ms
|
||||
|
||||
### 2. useEditorState pour la toolbar et les panels
|
||||
```typescript
|
||||
import { useEditorState } from '@tiptap/react'
|
||||
|
||||
// Au lieu de useEditor + editor.isActive() dans le render :
|
||||
const { isBold, isItalic, isHeading } = useEditorState({
|
||||
editor,
|
||||
selector: (ctx) => ({
|
||||
isBold: ctx.editor.isActive('bold'),
|
||||
isItalic: ctx.editor.isActive('italic'),
|
||||
isHeading: ctx.editor.isActive('heading'),
|
||||
}),
|
||||
})
|
||||
```
|
||||
- La toolbar et le panneau propriétés ne se re-rendent que quand leur slice d'état change
|
||||
- Actuellement, tout le composant editor re-render à chaque frappe -> la toolbar aussi
|
||||
|
||||
### 3. Isoler l'éditeur dans un composant dédié
|
||||
- Créer `NoteEditorCore` (composant wrapper) qui ne reçoit que les props strictement nécessaires
|
||||
- Les re-renders du parent (note-panel, sidebar ouverture, etc.) ne doivent PAS propager dans l'éditeur
|
||||
- React.memo sur le wrapper si besoin
|
||||
|
||||
### 4. NodeViews : trackNodeViewPosition: false par défaut
|
||||
- Les NodeViews React (LiveBlock, Chart, DatabaseBlock) ne doivent pas se re-re-render quand seul leur position dans le document change
|
||||
- TipTap PR #7828 (mai 2026) : shallow prop comparison + opt-in position tracking
|
||||
- Vérifier que chaque NodeView utilise `stopEvent()`, `ignoreMutation()`, et ne déclenche pas de setState inutile
|
||||
|
||||
### 5. Vérification
|
||||
- `console.count('editor render')` dans le composant éditeur pour mesurer le nombre de re-renders
|
||||
- Objectif : 0 re-render React pendant la frappe pure (seul ProseMirror DOM bouge)
|
||||
|
||||
---
|
||||
|
||||
## US-EDITOR-UX — Micro-Interactions de Saisie
|
||||
|
||||
> **Status :** À FAIRE
|
||||
> **Depends on :** US-NEXTGEN-EDITOR (drag handle et menu bloc doivent être en place)
|
||||
> **Source recherche :** Mintlify "22 UX improvements" (mai 2026), BlockNote v0.50, BlockNote v0.49
|
||||
|
||||
**Contexte :**
|
||||
Après les quick wins performance (US-EDITOR-PERF) et le drag handle (US-NEXTGEN-EDITOR), il reste des micro-interactions qui font la différence entre un éditeur "correct" et un éditeur "agréable". Mintlify a listé 22 améliorations UX en mai 2026 — voici les plus pertinentes pour Momento.
|
||||
|
||||
**En tant qu'utilisateur**, je veux que chaque interaction courante (insérer un bloc, déplacer du contenu, transformer un format) soit fluide et intuitive, sans recourir à des raccourcis clavier obscurs.
|
||||
|
||||
### 1. Sélection globale de blocs (Haute priorité)
|
||||
- Shift+clic pour sélectionner plusieurs blocs contigus
|
||||
- Drag de sélection multi-blocs
|
||||
- Actions groupées : supprimer, déplacer, transformer en masse
|
||||
- Visuel : blocs sélectionnés avec fond accent/5, bordure accent/30
|
||||
- **Inspiration :** Mintlify "Global Block Selection" — nettoyage de pages longues sans actions répétées
|
||||
|
||||
### 2. Slash menu redessiné (Haute priorité)
|
||||
- Type-to-search avec catégories visuelles (Texte, Média, Données, Intégré, IA)
|
||||
- Navigation clavier fluide (flèches + Entrée, Esc pour fermer)
|
||||
- Épinglage des 3-5 commandes les plus utilisées en haut
|
||||
- Description courte sous chaque item (ex. "Code" -> "Bloc de code avec coloration syntaxique")
|
||||
- Preview visuel au survol pour les blocs complexes (tableau, database, chart)
|
||||
- **Inspiration :** Mintlify slash menu redesign, BlockNote catégories
|
||||
|
||||
### 3. Placeholders contextuels par type de bloc (Moyenne priorité)
|
||||
- Paragraphe vide : "Tapez / pour insérer un bloc..."
|
||||
- Heading H1 vide : "Titre principal"
|
||||
- Heading H2 vide : "Titre de section"
|
||||
- TaskItem vide : "Ajouter une tâche"
|
||||
- Bloc de code vide : "Code..."
|
||||
- Bullet list vide : "Liste"
|
||||
- **Inspiration :** BlockNote "Helpful placeholders"
|
||||
|
||||
### 4. Collage intelligent étendu (Moyenne priorité)
|
||||
- Coller une URL HTTP(S) -> propose : lien hypertexte / intégration image / intégration vidéo
|
||||
- Coller du code (détecté par caractères spéciaux {}[];) -> propose : bloc de code avec auto-détection langage
|
||||
- Coller une image depuis le presse-papier -> upload direct (déjà en prod, vérifier la fluidité)
|
||||
- Coller du HTML riche -> nettoyage intelligent (conserver structure, supprimer styles inline superflus)
|
||||
- **Inspiration :** US-3 Smart Paste existe pour les blocs connectés — étendre au contenu générique
|
||||
|
||||
### 5. "Turn into" instant (Moyenne priorité)
|
||||
- Raccourci clavier : sélectionner du texte + `Cmd+Shift+H` -> cycle H1 > H2 > H3 > paragraphe
|
||||
- Via le menu bloc (US-2) : transformation instantanée sans flash ni re-render visible
|
||||
- Conserver le contenu et les attributs (gras, liens, etc.) lors de la conversion
|
||||
- **Inspiration :** Mintlify "Turn Blocks Into Anything"
|
||||
|
||||
### 6. Undo/redo visuel discret (Basse priorité)
|
||||
- Toast subtil (2s) : "Action annulée" / "Action rétablie"
|
||||
- Raccourci affiché dans le toast : "Cmd+Z pour annuler, Cmd+Shift+Z pour rétablir"
|
||||
- Ne pas utiliser toast pour les actions normales — seulement undo/redo pour confirmer le feedback
|
||||
|
||||
---
|
||||
|
||||
## US-EDITOR-MOBILE — Expérience Tactile & Toolbar Mobile
|
||||
|
||||
> **Status :** À FAIRE
|
||||
> **Depends on :** US-NEXTGEN-EDITOR (drag handle existant)
|
||||
> **Source recherche :** Notion mobile app, Obsidian mobile, benchmark 2026
|
||||
|
||||
**Contexte :**
|
||||
L'éditeur fonctionne sur mobile mais l'expérience est dégradée : la bubble menu est trop petite pour les doigts, le drag handle est masqué (prévu) mais il n'y a pas d'alternative tactile, et les sélections longues sont douloureuses en contenteditable.
|
||||
|
||||
**En tant qu'utilisateur mobile**, je veux pouvoir éditer mes notes confortablement depuis mon téléphone ou tablette, avec des contrôles adaptés au tactile.
|
||||
|
||||
### 1. Toolbar mobile adaptée
|
||||
- Remplacer la bubble menu desktop par une toolbar fixe en bas d'écran (viewport < 768px)
|
||||
- Boutons 44x44px minimum (Apple HIG)
|
||||
- 8 actions principales : Gras, Italique, Surligner, Lien, Liste, Titre, Code, Plus (menu étendu)
|
||||
- Scroll horizontal si plus d'actions
|
||||
- **Inspiration :** Notion mobile toolbar
|
||||
|
||||
### 2. Menu bloc tactile
|
||||
- Pas de drag handle sur mobile (déjà prévu dans US-1)
|
||||
- Alternative : swipe gauche sur un bloc -> reveal actions (supprimer, dupliquer, transformer)
|
||||
- Ou : tap long sur un bloc -> menu contextuel mobile natif (action sheet iOS / bottom sheet Android)
|
||||
- Bouton "Déplacer" dans le menu -> mode réorganisation avec poignées tactiles
|
||||
|
||||
### 3. Sélection de texte améliorée
|
||||
- Les sélections longues en contenteditable sont frustrantes sur mobile
|
||||
- Ajouter un bouton "Sélectionner tout le bloc" dans le menu bloc tactile
|
||||
- Double-tap sélectionne le mot, triple-tap sélectionne le paragraphe (comportement natif iOS/Android, vérifier que TipTap ne l'écrase pas)
|
||||
|
||||
### 4. Performance mobile
|
||||
- Les NodeViews React lourds (Chart, DatabaseBlock) doivent avoir un fallback léger sur mobile
|
||||
- Désactiver les animations de la bubble menu sur mobile (prefers-reduced-motion)
|
||||
- `immediatelyRender: false` déjà en place — bon pour le premier rendu mobile
|
||||
|
||||
---
|
||||
|
||||
## US-EDITOR-MARKDOWN — Rendu WYSIWYG Markdown Fidèle
|
||||
|
||||
> **Status :** À FAIRE (low priority)
|
||||
> **Depends on :** rien (évaluation Milkdown)
|
||||
> **Source recherche :** Milkdown v7.20, "Human Markdown" extension VSCode, round-trip byte-for-byte
|
||||
|
||||
**Contexte :**
|
||||
Momento stocke les notes en HTML (TipTap). Mais les notes de type `markdown` existent aussi. Le problème classique : éditer en riche et voir le Markdown reformatté intégralement (indentations changées, lignes vides supprimées, `##` convertis en soulignements). Milkdown (11k+ stars, ProseMirror + remark) résout ce problème avec un round-trip byte-for-byte.
|
||||
|
||||
**En tant qu'utilisateur**, je veux que mes fichiers Markdown restent intacts quand je les édite en mode visuel — pas de diff parasite sur chaque modification.
|
||||
|
||||
### 1. Évaluation technique Milkdown
|
||||
- Installer `@milkdown/core` + `@milkdown/preset-commonmark` + `@milkdown/preset-gfm`
|
||||
- Benchmarker le round-trip : ouvrir un .md, éditer un paragraphe, sauvegarder, vérifier que seul ce paragraphe change dans le diff
|
||||
- Comparer avec la solution actuelle (TipTap HTML storage) pour les notes markdown
|
||||
- **Référence :** "Human Markdown" VSCode extension (Milkdown + byte-for-byte tests)
|
||||
|
||||
### 2. Mode d'édition dual (si Milkdown adopté)
|
||||
- Toggle dans la toolbar : mode Visuel (WYSIWYG) / mode Brut (CodeMirror)
|
||||
- Transition en <100ms, même position de scroll
|
||||
- Le mode Visuel affiche le rendu live (titres, listes, tables, images, checkboxes cliquables)
|
||||
- Le mode Brut affiche le Markdown source avec coloration syntaxique
|
||||
- **Inspiration :** "Human Markdown" — Cmd+Shift+V pour basculer
|
||||
|
||||
### 3. Intégration avec les notes existantes
|
||||
- Notes type `richtext` : inchangé (stockage HTML TipTap)
|
||||
- Notes type `markdown` : mode dual avec Milkdown
|
||||
- Détection automatique du type à l'ouverture
|
||||
- Conversion possible : `richtext` -> `markdown` (export) et `markdown` -> `richtext` (import)
|
||||
|
||||
### 4. Support GFM complet
|
||||
- Tables Markdown rendues comme de vrais tableaux éditables
|
||||
- Task lists avec checkboxes cliquables
|
||||
- Footnotes rendues inline
|
||||
- Frontmatter YAML en carte collapsible en haut de document
|
||||
- **Inspiration :** "Human Markdown" — GFM complet, Shiki pour le code
|
||||
|
||||
Reference in New Issue
Block a user