329 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			329 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
# Mode Édition Markdown - Quick Start Guide
 | 
						|
 | 
						|
## 🚀 Démarrage rapide
 | 
						|
 | 
						|
### Pour tester la fonctionnalité
 | 
						|
 | 
						|
1. **Démarrer le serveur de développement:**
 | 
						|
   ```bash
 | 
						|
   npm run dev
 | 
						|
   ```
 | 
						|
 | 
						|
2. **Ouvrir ObsiViewer dans le navigateur:**
 | 
						|
   ```
 | 
						|
   http://localhost:4200
 | 
						|
   ```
 | 
						|
 | 
						|
3. **Ouvrir une note Markdown**
 | 
						|
 | 
						|
4. **Cliquer sur le bouton "Éditer"** (icône crayon à gauche de "Open in Full Screen")
 | 
						|
 | 
						|
5. **L'éditeur CodeMirror 6 se charge:**
 | 
						|
   - Modifier le contenu
 | 
						|
   - Utiliser `Ctrl+S` (ou `Cmd+S`) pour sauvegarder
 | 
						|
   - Cliquer sur "Close" pour revenir en lecture
 | 
						|
 | 
						|
## 🎯 Fonctionnalités implémentées
 | 
						|
 | 
						|
### ✅ Bouton "Éditer"
 | 
						|
- Ajouté dans `markdown-viewer.component.ts` (ligne 48-59)
 | 
						|
- Placé à gauche du bouton "Open in Full Screen"
 | 
						|
- Icône lucide-edit-3 (crayon)
 | 
						|
- Émet un événement `editModeRequested`
 | 
						|
 | 
						|
### ✅ Service d'état
 | 
						|
- `EditorStateService` gère le mode `'view' | 'edit'`
 | 
						|
- Signal-based pour réactivité
 | 
						|
- Tracking du `isDirty` state
 | 
						|
 | 
						|
### ✅ Composant éditeur
 | 
						|
- `MarkdownEditorComponent` (standalone)
 | 
						|
- CodeMirror 6 avec extensions:
 | 
						|
  - Markdown syntax highlighting
 | 
						|
  - Line numbers
 | 
						|
  - Active line highlighting
 | 
						|
  - Bracket matching
 | 
						|
  - Search & replace (Ctrl+F)
 | 
						|
  - History (undo/redo)
 | 
						|
  - Autocomplete
 | 
						|
  - Word wrap toggle
 | 
						|
 | 
						|
### ✅ Toolbar d'édition
 | 
						|
- **Save** - Sauvegarde (Ctrl+S) + toast
 | 
						|
- **Wrap** - Toggle word wrap
 | 
						|
- **Undo** - Annuler
 | 
						|
- **Redo** - Refaire
 | 
						|
- **Close** - Quitter avec confirmation si dirty
 | 
						|
 | 
						|
### ✅ Lazy loading
 | 
						|
- CodeMirror 6 chargé dynamiquement
 | 
						|
- Pas d'impact sur les performances en mode lecture
 | 
						|
- Import async dans `smart-file-viewer.component.ts`
 | 
						|
 | 
						|
### ✅ Sauvegarde
 | 
						|
- Intégration avec `VaultService.saveMarkdown()`
 | 
						|
- Autosave après 5s d'inactivité
 | 
						|
- Toast de succès/erreur via `ToastService`
 | 
						|
 | 
						|
### ✅ Navigation guard
 | 
						|
- `EditorCanDeactivateGuard` empêche la perte de données
 | 
						|
- Confirmation si modifications non sauvegardées
 | 
						|
- Protection beforeunload (fermeture navigateur)
 | 
						|
 | 
						|
### ✅ Thème Dark/Light
 | 
						|
- Variables CSS dans `codemirror.css`
 | 
						|
- Synchronisation automatique avec le thème du site
 | 
						|
- MutationObserver sur `<html class="dark">`
 | 
						|
 | 
						|
### ✅ Responsive
 | 
						|
- Toolbar compacte sur mobile (≤ 640px)
 | 
						|
- Font-size ajustée
 | 
						|
- Padding réduit
 | 
						|
- Labels cachés, icônes conservées
 | 
						|
 | 
						|
## 📁 Fichiers créés/modifiés
 | 
						|
 | 
						|
### Nouveaux fichiers
 | 
						|
 | 
						|
```
 | 
						|
src/
 | 
						|
├── app/features/editor/
 | 
						|
│   ├── markdown-editor.module.ts              ← Module lazy
 | 
						|
│   ├── markdown-editor.component.ts           ← Éditeur CodeMirror 6
 | 
						|
│   └── editor-can-deactivate.guard.ts        ← Guard navigation
 | 
						|
├── services/
 | 
						|
│   └── editor-state.service.ts               ← Gestion d'état
 | 
						|
├── styles/
 | 
						|
│   └── codemirror.css                        ← Styles globaux
 | 
						|
└── docs/
 | 
						|
    ├── MARKDOWN_EDITOR.md                    ← Doc complète
 | 
						|
    └── MARKDOWN_EDITOR_QUICKSTART.md         ← Ce fichier
 | 
						|
```
 | 
						|
 | 
						|
### Fichiers modifiés
 | 
						|
 | 
						|
```
 | 
						|
src/
 | 
						|
├── components/
 | 
						|
│   ├── markdown-viewer/
 | 
						|
│   │   └── markdown-viewer.component.ts      ← Bouton "Éditer" + output
 | 
						|
│   └── smart-file-viewer/
 | 
						|
│       └── smart-file-viewer.component.ts    ← Lazy loading éditeur
 | 
						|
├── styles.css                                ← Import codemirror.css
 | 
						|
└── package.json                              ← Dépendances CodeMirror 6
 | 
						|
```
 | 
						|
 | 
						|
## 🧪 Tests à effectuer
 | 
						|
 | 
						|
### Test 1: Basculement lecture ↔ édition
 | 
						|
 | 
						|
```bash
 | 
						|
# Ouvrir une note
 | 
						|
# Cliquer sur "Éditer"
 | 
						|
# ✓ Transition fluide
 | 
						|
# ✓ Contenu chargé
 | 
						|
# ✓ Cursor visible
 | 
						|
# Cliquer sur "Close"
 | 
						|
# ✓ Retour en lecture
 | 
						|
```
 | 
						|
 | 
						|
### Test 2: Sauvegarde
 | 
						|
 | 
						|
```bash
 | 
						|
# En mode édition
 | 
						|
# Modifier le contenu
 | 
						|
# Appuyer sur Ctrl+S
 | 
						|
# ✓ Toast "Saved successfully"
 | 
						|
# ✓ Flag dirty réinitialisé
 | 
						|
# Rafraîchir la page
 | 
						|
# ✓ Modifications persistées
 | 
						|
```
 | 
						|
 | 
						|
### Test 3: Navigation guard
 | 
						|
 | 
						|
```bash
 | 
						|
# En mode édition
 | 
						|
# Modifier le contenu
 | 
						|
# Essayer de fermer l'onglet
 | 
						|
# ✓ Confirmation beforeunload
 | 
						|
# Confirmer "Quitter"
 | 
						|
# Rouvrir la note
 | 
						|
# ✓ Modifications non sauvegardées perdues (normal)
 | 
						|
```
 | 
						|
 | 
						|
### Test 4: Autosave
 | 
						|
 | 
						|
```bash
 | 
						|
# En mode édition
 | 
						|
# Modifier le contenu
 | 
						|
# Attendre 6 secondes
 | 
						|
# ✓ Toast "Saved successfully" automatique
 | 
						|
# ✓ Flag dirty réinitialisé
 | 
						|
```
 | 
						|
 | 
						|
### Test 5: Thème Dark/Light
 | 
						|
 | 
						|
```bash
 | 
						|
# En mode édition
 | 
						|
# Basculer le thème (dark ↔ light)
 | 
						|
# ✓ Couleurs de l'éditeur changent
 | 
						|
# ✓ Contraste lisible
 | 
						|
# ✓ Cursor visible
 | 
						|
```
 | 
						|
 | 
						|
### Test 6: Responsive mobile
 | 
						|
 | 
						|
```bash
 | 
						|
# Ouvrir DevTools
 | 
						|
# Passer en mode mobile (375px)
 | 
						|
# Entrer en mode édition
 | 
						|
# ✓ Toolbar compacte
 | 
						|
# ✓ Boutons visibles
 | 
						|
# ✓ Labels cachés (icônes seules)
 | 
						|
# ✓ Scroll fluide
 | 
						|
```
 | 
						|
 | 
						|
### Test 7: Note lourde
 | 
						|
 | 
						|
```bash
 | 
						|
# Ouvrir une note > 5000 lignes
 | 
						|
# Entrer en mode édition
 | 
						|
# ✓ Chargement rapide (< 1s)
 | 
						|
# ✓ Scroll fluide
 | 
						|
# ✓ Pas de lag à la frappe
 | 
						|
```
 | 
						|
 | 
						|
### Test 8: Front-matter YAML
 | 
						|
 | 
						|
```bash
 | 
						|
# Ouvrir une note avec front-matter
 | 
						|
---
 | 
						|
title: Test
 | 
						|
tags: [test, markdown]
 | 
						|
---
 | 
						|
# Contenu
 | 
						|
 | 
						|
# Entrer en mode édition
 | 
						|
# ✓ Front-matter affiché correctement
 | 
						|
# Modifier uniquement le corps
 | 
						|
# Sauvegarder
 | 
						|
# ✓ Front-matter préservé intact
 | 
						|
```
 | 
						|
 | 
						|
## 🐛 Debugging
 | 
						|
 | 
						|
### Activer les logs
 | 
						|
 | 
						|
Ouvrir la console DevTools et chercher:
 | 
						|
 | 
						|
```
 | 
						|
[SmartFileViewer] Editor loaded successfully
 | 
						|
[SmartFileViewer] Editor unloaded
 | 
						|
```
 | 
						|
 | 
						|
### Inspecter l'état
 | 
						|
 | 
						|
Dans la console:
 | 
						|
 | 
						|
```javascript
 | 
						|
// Injecter le service dans la console
 | 
						|
const editorState = ng.probe($0).injector.get(EditorStateService);
 | 
						|
 | 
						|
// Vérifier l'état
 | 
						|
console.log(editorState.mode());        // 'view' | 'edit'
 | 
						|
console.log(editorState.isDirty());     // true | false
 | 
						|
console.log(editorState.currentPath()); // chemin du fichier
 | 
						|
```
 | 
						|
 | 
						|
### Network tab
 | 
						|
 | 
						|
Vérifier que CodeMirror n'est chargé qu'en mode édition:
 | 
						|
 | 
						|
1. Ouvrir Network tab (DevTools)
 | 
						|
2. Ouvrir une note (mode lecture)
 | 
						|
3. ✓ Aucun fichier `codemirror` chargé
 | 
						|
4. Cliquer sur "Éditer"
 | 
						|
5. ✓ Fichiers `@codemirror/*` chargés dynamiquement
 | 
						|
 | 
						|
## 📦 Dépendances installées
 | 
						|
 | 
						|
```bash
 | 
						|
npm install @codemirror/view @codemirror/state @codemirror/language \
 | 
						|
  @codemirror/lang-markdown @codemirror/commands @codemirror/search \
 | 
						|
  @codemirror/autocomplete @codemirror/lint @codemirror/legacy-modes \
 | 
						|
  @lezer/highlight
 | 
						|
```
 | 
						|
 | 
						|
**Taille bundle:**
 | 
						|
- Mode lecture: +0 KB (lazy loading)
 | 
						|
- Mode édition: ~150 KB (chargé à la demande)
 | 
						|
 | 
						|
## 🎨 Personnalisation
 | 
						|
 | 
						|
### Modifier le thème
 | 
						|
 | 
						|
Éditer `src/styles/codemirror.css`:
 | 
						|
 | 
						|
```css
 | 
						|
:root {
 | 
						|
  --cm-cursor: #your-color;
 | 
						|
  --cm-selection-bg: #your-color;
 | 
						|
  /* ... */
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
### Ajouter une extension CodeMirror
 | 
						|
 | 
						|
Dans `markdown-editor.component.ts`, méthode `initializeEditor()`:
 | 
						|
 | 
						|
```typescript
 | 
						|
const initialState = EditorState.create({
 | 
						|
  extensions: [
 | 
						|
    // ... extensions existantes
 | 
						|
    myCustomExtension(),
 | 
						|
  ]
 | 
						|
});
 | 
						|
```
 | 
						|
 | 
						|
### Personnaliser la toolbar
 | 
						|
 | 
						|
Éditer le template de `markdown-editor.component.ts`:
 | 
						|
 | 
						|
```html
 | 
						|
<div class="markdown-editor__toolbar-right">
 | 
						|
  <!-- Ajouter votre bouton ici -->
 | 
						|
  <button (click)="myCustomAction()">...</button>
 | 
						|
</div>
 | 
						|
```
 | 
						|
 | 
						|
## 🚦 Critères d'acceptation (DoD)
 | 
						|
 | 
						|
- [x] Bouton "Éditer" visible à gauche de "Open in Full Screen"
 | 
						|
- [x] Passage lecture ↔ édition sans recharger la page
 | 
						|
- [x] CodeMirror 6 configuré (Markdown, YAML, line numbers, wrap)
 | 
						|
- [x] Ctrl/Cmd+S déclenche save() via VaultService
 | 
						|
- [x] Toast "Enregistré" ou erreur I/O
 | 
						|
- [x] Bouton "Close" ramène en vue lecture
 | 
						|
- [x] Thème Dark/Light synchronisé
 | 
						|
- [x] Responsive mobile (toolbar compacte)
 | 
						|
- [x] Navigation guard si modifications non sauvegardées
 | 
						|
- [x] Autosave après 5s d'inactivité
 | 
						|
- [x] Tests manuels validés
 | 
						|
 | 
						|
## 🎓 Ressources
 | 
						|
 | 
						|
### Documentation CodeMirror 6
 | 
						|
- [Official Guide](https://codemirror.net/docs/guide/)
 | 
						|
- [API Reference](https://codemirror.net/docs/ref/)
 | 
						|
- [Extensions](https://codemirror.net/docs/extensions/)
 | 
						|
 | 
						|
### Angular Signals
 | 
						|
- [Angular Signals Guide](https://angular.io/guide/signals)
 | 
						|
 | 
						|
### Architecture
 | 
						|
- Voir `docs/MARKDOWN_EDITOR.md` pour l'architecture détaillée
 | 
						|
 | 
						|
---
 | 
						|
 | 
						|
**Prêt à tester?** Lance `npm run dev` et ouvre une note! 🚀
 |