54 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			54 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # Dessins (Excalidraw)
 | |
| 
 | |
| Cette section décrit l'intégration d'Excalidraw dans ObsiViewer.
 | |
| 
 | |
| ## Fonctionnalités
 | |
| 
 | |
| - **Édition**: ouverture des fichiers `.excalidraw` de la voûte dans un éditeur dédié.
 | |
| - **Autosave**: sauvegarde automatique après 800 ms d'inactivité (avec ETag/If-Match côté serveur).
 | |
| - **Exports**: génération de vignettes PNG/SVG enregistrées en sidecar (`.excalidraw.png|.svg`).
 | |
| - **Thème**: synchronisation avec le thème Angular (`light`/`dark`).
 | |
| - **Lazy-load**: Excalidraw n'est chargé que lors de l'ouverture de l'éditeur.
 | |
| 
 | |
| ## Utilisation
 | |
| 
 | |
| - **Ouvrir un dessin**: dans l'explorateur de fichiers, cliquer un fichier avec l'extension `.excalidraw`. L'application bascule dans la vue `Dessins`.
 | |
| - **Sauvegarde**: toute modification de la scène déclenche un événement `scene-change` capturé par l'éditeur Angular. La sauvegarde s'exécute automatiquement après 800 ms. Un indicateur "Saving…" s'affiche pendant l'opération.
 | |
| - **Exporter**: utiliser les boutons "Export PNG" ou "Export SVG". Les fichiers sidecar sont écrits via l'API `/api/files/blob/:path`.
 | |
| 
 | |
| ## Détails techniques
 | |
| 
 | |
| - **Web Component**: `<excalidraw-editor>` est défini via `react-to-webcomponent` sans Shadow DOM (`shadow:false`) pour éviter les soucis d'overlays/styling.
 | |
| - **Wrapper**: `web-components/excalidraw/ExcalidrawElement.tsx` monte `<Excalidraw />` et expose des méthodes (`getScene()`, `exportPNG()`, `exportSVG()`, `setScene()`, `refresh()`).
 | |
| - **Événements**: le wrapper émet `ready` et `scene-change` (kebab-case).
 | |
| - **Thème**: la prop `theme` est propagée à Excalidraw. Tout changement de `ThemeService` se reflète automatiquement.
 | |
| - **Backend**: endpoints
 | |
|   - `GET /api/files/:path` lit des `.excalidraw` avec validation Zod (schéma minimal) et renvoie un `ETag`.
 | |
|   - `PUT /api/files/:path` écrit de façon atomique, vérifie `If-Match` si fourni, limite 10 MB.
 | |
|   - `PUT /api/files/blob/:path` écrit un binaire `.png` ou `.svg` (≤10 MB).
 | |
|   - `/api/files/metadata` fusionne la liste Meilisearch avec les `.excalidraw` trouvés sur FS.
 | |
| 
 | |
| ## Sécurité
 | |
| 
 | |
| - **JSON only**: aucun HTML n'est interprété à partir du contenu `.excalidraw`.
 | |
| - **Validation**: schéma Zod minimal (structure conforme au format Excalidraw) + limites de taille.
 | |
| 
 | |
| ## Accessibilité
 | |
| 
 | |
| - L'éditeur est inséré dans une zone avec focus gérable au clavier. Les actions d'export possèdent des libellés.
 | |
| 
 | |
| ## Développement
 | |
| 
 | |
| - **Lazy registration**: `DrawingsEditorComponent` appelle `import('../../../../web-components/excalidraw/define')` lors de l'initialisation.
 | |
| - **Schéma**: `schemas: [CUSTOM_ELEMENTS_SCHEMA]` est appliqué au composant éditeur.
 | |
| 
 | |
| ## Tests à prévoir
 | |
| 
 | |
| - **Unitaires**: debounce/autosave, services fichiers (mocks HTTP), validation serveur (schéma Zod).
 | |
| - **E2E**: ouvrir → modifier → autosave → recharger → modifications présentes ; export PNG ; bascule thème.
 | |
| 
 | |
| ## Limitations actuelles
 | |
| 
 | |
| - Boîte de dialogue "Nouveau dessin" non incluse (à ajouter si besoin).
 | |
| - Refresh API disponible mais non appelée automatiquement sur redimensionnement (peut être déclenchée en option selon contexte UI).
 |