ObsiViewer/docs/EXCALIDRAW_SAVE_FIX.md

217 lines
6.4 KiB
Markdown

# Fix de la Sauvegarde Excalidraw - Diagnostic et Solution
## Problème Initial
1. **Bouton Sauvegarde ne déclenchait aucune requête réseau**
2. **Boutons Export PNG/SVG désactivés en permanence**
## Cause Racine
Le problème était dans la **séquence de binding des listeners** :
### Séquence défaillante :
1. `ngAfterViewInit()` s'exécute
2. Tente de binder les listeners sur `<excalidraw-editor>`
3. **Mais l'élément n'existe pas encore** car il est derrière `*ngIf="!isLoading()"`
4. Les listeners ne sont jamais attachés
5. L'événement `scene-change` n'est jamais capturé
6. `excalidrawReady` reste `false`
7. Les exports restent désactivés
## Solution Implémentée
### 1. Binding au bon moment
**Avant** :
```typescript
ngAfterViewInit(): void {
this.bindEditorHostListeners(); // ❌ Trop tôt
setTimeout(() => this.bindEditorHostListeners(), 0);
}
```
**Après** :
```typescript
onExcalidrawReady() {
this.excalidrawReady = true;
this.bindEditorHostListeners(); // ✅ Après le (ready) event
}
ngAfterViewInit(): void {
// L'élément sera bindé via (ready)="onExcalidrawReady()"
}
```
Le template a déjà `(ready)="onExcalidrawReady()"` qui se déclenche quand l'API Excalidraw est disponible.
### 2. Indicateur Visuel de Sauvegarde
Remplacement du bouton texte par un **indicateur visuel avec icône de disquette** :
#### États :
- 🔴 **Rouge** + "Non sauvegardé" : modifications non enregistrées
-**Gris** + "Sauvegardé" : tout est sauvegardé
- 🟡 **Jaune** + "Sauvegarde..." + animation pulse : sauvegarde en cours
#### Comportement :
- **Cliquable** : force une sauvegarde immédiate
- **Tooltip** : indique l'état et suggère Ctrl+S
- **Toast** : notification "Sauvegarde réussie" ou "Erreur de sauvegarde"
### 3. Sauvegarde Automatique
**Pipeline RxJS** :
```typescript
fromEvent<CustomEvent>(host, 'scene-change')
.pipe(
debounceTime(2000), // Attend 2s après le dernier changement
distinctUntilChanged(), // Ignore si identique au dernier hash
switchMap(() => save()), // Sauvegarde
)
```
### 4. Logs de Diagnostic
Ajout de logs console pour tracer le flux :
- `🎨 Excalidraw Ready - Binding listeners`
- `🔗 Binding Excalidraw host listeners`
- `📝 Scene changed`
- `💾 Autosaving...`
- `✅ Autosave successful`
- `💾 Manual save triggered`
- `📤 Sending save request...`
- `✅ Manual save successful`
## Fichiers Modifiés
### `src/app/features/drawings/drawings-editor.component.ts`
- Déplacement du binding dans `onExcalidrawReady()`
- Ajout de logs pour diagnostic
- Toast sur sauvegarde manuelle
- Debounce augmenté à 2s pour l'autosave
### `src/app/features/drawings/drawings-editor.component.html`
- Remplacement du bouton "💾 Sauvegarder" par indicateur visuel
- Icône SVG de disquette avec états de couleur
- Suppression des indicateurs redondants ("Modifications non enregistrées")
- Conservation uniquement des erreurs et conflits
## Comment Tester
### 1. Ouvrir un fichier
```
1. Ouvrir tests.excalidraw.md
2. Vérifier dans la console : "🎨 Excalidraw Ready"
3. Vérifier : "🔗 Binding Excalidraw host listeners"
```
### 2. Test Sauvegarde Automatique
```
1. Ajouter un élément au dessin
2. Vérifier console : "📝 Scene changed"
3. Attendre 2 secondes
4. Vérifier console : "💾 Autosaving..."
5. Vérifier console : "✅ Autosave successful"
6. Vérifier requête réseau : PUT /api/files?path=...
7. Vérifier indicateur : 🔴 Rouge → ⚫ Gris
```
### 3. Test Sauvegarde Manuelle
```
1. Ajouter un élément au dessin
2. Cliquer sur l'indicateur (disquette rouge)
3. Vérifier console : "💾 Manual save triggered"
4. Vérifier console : "📤 Sending save request..."
5. Vérifier console : "✅ Manual save successful"
6. Vérifier toast : "Sauvegarde réussie"
7. Vérifier requête réseau : PUT /api/files?path=...
8. Vérifier indicateur : 🔴 → ⚫
```
### 4. Test Export PNG/SVG
```
1. S'assurer que le fichier est chargé
2. Vérifier que les boutons Export sont activés
3. Cliquer "🖼️ Export PNG"
4. Vérifier requête réseau : PUT /api/files/blob?path=...png
5. Vérifier toast si erreur
```
### 5. Test Ctrl+S
```
1. Modifier le dessin
2. Appuyer Ctrl+S (ou Cmd+S sur Mac)
3. Vérifier console : "💾 Manual save triggered"
4. Vérifier toast : "Sauvegarde réussie"
```
## Comportement Attendu
### Au Chargement
1. Spinner de chargement
2. GET `/api/files?path=tests.excalidraw.md`
3. `🎨 Excalidraw Ready - Binding listeners`
4. `🔗 Binding Excalidraw host listeners`
5. Indicateur : ⚫ Gris "Sauvegardé"
6. Exports : activés
### Pendant l'Édition
1. Ajout d'un élément
2. `📝 Scene changed`
3. Indicateur : 🔴 Rouge "Non sauvegardé"
4. Attente de 2 secondes
5. `💾 Autosaving...`
6. PUT `/api/files?path=...`
7. `✅ Autosave successful`
8. Indicateur : ⚫ Gris "Sauvegardé"
### Après Clic Sauvegarde
1. `💾 Manual save triggered`
2. `📤 Sending save request...`
3. PUT `/api/files?path=...`
4. `✅ Manual save successful`
5. Toast : "Sauvegarde réussie"
6. Indicateur : ⚫ Gris "Sauvegardé"
## Troubleshooting
### Pas de logs dans la console
→ Le composant ne charge pas, vérifier `ngOnInit()`
### "⚠️ Cannot bind listeners - host element not found"
→ L'élément web component n'est pas créé, vérifier le template `*ngIf`
### "❌ No host element" lors du clic Sauvegarde
`@ViewChild` ne trouve pas l'élément, vérifier `#editorEl`
### "❌ No scene data"
`getScene()` retourne null, vérifier que l'API Excalidraw est initialisée
### Pas de requête réseau
→ Vérifier dans la console les logs "💾" et "📤"
→ Si absents, le binding n'a pas eu lieu
### Export désactivés
→ Vérifier `excalidrawReady` dans le composant
→ Doit être `true` après `onExcalidrawReady()`
## Prochaines Étapes
Une fois le problème résolu (les logs apparaissent et les requêtes passent) :
1. **Retirer les logs de debug** dans `drawings-editor.component.ts`
2. **Tester la sauvegarde intensive** (ajouter/supprimer rapidement des éléments)
3. **Tester les conflits** (modifier le fichier externellement)
4. **Vérifier la performance** (fichiers avec 100+ éléments)
5. **Tester sur mobile** (responsive + touch)
## Résumé
✅ Binding des listeners au bon moment (après `ready`)
✅ Indicateur visuel clair (disquette colorée)
✅ Sauvegarde automatique (2s debounce)
✅ Sauvegarde manuelle (clic ou Ctrl+S)
✅ Toast notifications
✅ Logs de diagnostic
✅ Export PNG/SVG fonctionnels