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).
 |