6.4 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	Fix de la Sauvegarde Excalidraw - Diagnostic et Solution
Problème Initial
- Bouton Sauvegarde ne déclenchait aucune requête réseau
- 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 :
- ngAfterViewInit()s'exécute
- Tente de binder les listeners sur <excalidraw-editor>
- Mais l'élément n'existe pas encore car il est derrière *ngIf="!isLoading()"
- Les listeners ne sont jamais attachés
- L'événement scene-changen'est jamais capturé
- excalidrawReadyreste- false
- Les exports restent désactivés
Solution Implémentée
1. Binding au bon moment
Avant :
ngAfterViewInit(): void {
  this.bindEditorHostListeners(); // ❌ Trop tôt
  setTimeout(() => this.bindEditorHostListeners(), 0);
}
Après :
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 :
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
- Spinner de chargement
- GET /api/files?path=tests.excalidraw.md
- 🎨 Excalidraw Ready - Binding listeners
- 🔗 Binding Excalidraw host listeners
- Indicateur : ⚫ Gris "Sauvegardé"
- Exports : activés
Pendant l'Édition
- Ajout d'un élément
- 📝 Scene changed
- Indicateur : 🔴 Rouge "Non sauvegardé"
- Attente de 2 secondes
- 💾 Autosaving...
- PUT /api/files?path=...
- ✅ Autosave successful
- Indicateur : ⚫ Gris "Sauvegardé"
Après Clic Sauvegarde
- 💾 Manual save triggered
- 📤 Sending save request...
- PUT /api/files?path=...
- ✅ Manual save successful
- Toast : "Sauvegarde réussie"
- 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) :
- Retirer les logs de debug dans drawings-editor.component.ts
- Tester la sauvegarde intensive (ajouter/supprimer rapidement des éléments)
- Tester les conflits (modifier le fichier externellement)
- Vérifier la performance (fichiers avec 100+ éléments)
- 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