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:
Antigravity
2026-05-27 19:45:15 +00:00
parent 2de66a863d
commit f46654f574
99 changed files with 29948 additions and 919 deletions

View File

@@ -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 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