136 lines
5.5 KiB
Markdown
136 lines
5.5 KiB
Markdown
# Correctif Trash Explorer - Résumé Technique
|
|
|
|
## Problème Initial
|
|
La section Trash n'affichait pas l'arborescence du dossier `.trash` et ne permettait pas de cliquer sur un dossier pour charger ses notes dans la liste.
|
|
|
|
## Causes Identifiées
|
|
|
|
### 1. **Bouton accordion Trash émet incorrectement un événement**
|
|
**Fichier**: `src/app/features/sidebar/nimbus-sidebar.component.ts`
|
|
**Ligne**: 90
|
|
**Problème**: Le bouton toggle de la section Trash émettait `folderSelected.emit('.trash')` au click, ce qui changeait le filtre de Notes-liste au lieu de juste ouvrir/fermer l'accordion.
|
|
**Solution**: Retrait de l'émission au click du bouton accordion.
|
|
|
|
```typescript
|
|
// AVANT
|
|
<button (click)="open.trash = !open.trash; folderSelected.emit('.trash')">
|
|
|
|
// APRÈS
|
|
<button (click)="open.trash = !open.trash">
|
|
```
|
|
|
|
### 2. **TrashExplorerComponent n'émet pas folderSelected**
|
|
**Fichier**: `src/app/layout/sidebar/trash/trash-explorer.component.ts`
|
|
**Ligne**: 91-94
|
|
**Problème**: La méthode `onFolderClick()` du composant parent toggle le dossier mais n'émet PAS l'événement `folderSelected`. Donc quand l'utilisateur clique sur un dossier trash, le parent (nimbus-sidebar) ne reçoit pas l'événement et ne peut pas mettre à jour `folderFilter` dans app-shell-nimbus.
|
|
|
|
**Solution**: Ajout de l'émission de `folderSelected` avec le path du dossier cliqué.
|
|
|
|
```typescript
|
|
// AVANT
|
|
onFolderClick(folder: VaultFolder) {
|
|
this.vault.toggleFolder(folder.path);
|
|
}
|
|
|
|
// APRÈS
|
|
onFolderClick(folder: VaultFolder) {
|
|
this.vault.toggleFolder(folder.path);
|
|
this.folderSelected.emit(folder.path);
|
|
}
|
|
```
|
|
|
|
## Flux Complet Corrigé
|
|
|
|
1. **Utilisateur clique sur un dossier dans Trash** (ex: `.trash/old-folder`)
|
|
2. `TrashExplorerComponent.onFolderClick()` est appelé
|
|
3. Le dossier est toggle ouvert/fermé via `vault.toggleFolder()`
|
|
4. L'événement `folderSelected` est émis avec le path `.trash/old-folder`
|
|
5. `NimbusSidebarComponent` propage l'événement vers `AppShellNimbusComponent`
|
|
6. `AppShellNimbusComponent.onFolderSelected()` définit `this.folderFilter = '.trash/old-folder'`
|
|
7. `NotesListComponent` reçoit `folderFilter` en input
|
|
8. Le computed `filtered()` filtre les notes où `originalPath` commence par `.trash/old-folder`
|
|
9. Les notes du dossier trash s'affichent dans la liste
|
|
|
|
## Architecture Existante Validée
|
|
|
|
### VaultService - buildTrashTree()
|
|
- ✅ Parse correctement les chemins trash via `parseTrashFolderSegments()`
|
|
- ✅ Construit l'arborescence avec `ensureTrashFolderPath()`
|
|
- ✅ Les badges de compte sont calculés par `calculateTrashFolderCounts()`
|
|
- ✅ `.trash` est exclu de la section Folders via `sortAndCleanFolderChildren()`
|
|
|
|
### NotesListComponent - Filtrage
|
|
- ✅ Le filtre `folderFilter` fonctionne avec les chemins trash
|
|
- ✅ Compare `originalPath` avec le folder passé (égalité ou startsWith)
|
|
- ✅ Compatible avec les chemins `.trash/subfolder`
|
|
|
|
### Backend API
|
|
- ✅ `/api/vault` charge tous les fichiers .md y compris `.trash`
|
|
- ✅ Les `filePath` sont relatifs au vault: `.trash/old-folder/note.md`
|
|
- ✅ Les `originalPath` sont sans extension: `.trash/old-folder/note`
|
|
|
|
## Fichiers Modifiés
|
|
|
|
1. **src/app/features/sidebar/nimbus-sidebar.component.ts**
|
|
- Retrait émission incorrecte au click accordion Trash
|
|
|
|
2. **src/app/layout/sidebar/trash/trash-explorer.component.ts**
|
|
- Ajout émission `folderSelected` au click sur dossier
|
|
|
|
3. **.env**
|
|
- VAULT_PATH pointant vers `./vault` pour tests
|
|
|
|
4. **vault/.trash/** (fichiers test créés)
|
|
- deleted-note-1.md
|
|
- old-folder/old-note-2.md
|
|
- old-folder/old-note-3.md
|
|
- archive/archived-note.md
|
|
|
|
## Critères d'Acceptation ✅
|
|
|
|
- [x] La section Trash affiche l'arborescence réelle du dossier `.trash`
|
|
- [x] Cliquer un dossier dans Trash charge ses fichiers dans Notes-liste
|
|
- [x] Les badges affichent le nombre correct de notes (récursif)
|
|
- [x] `.trash` n'apparaît pas dans la section Folders
|
|
- [x] États hover/sélection cohérents avec autres sections
|
|
- [x] Dark mode compatible (styles existants)
|
|
- [x] Cas vide géré avec empty-state "La corbeille est vide"
|
|
|
|
## Tests Suggérés
|
|
|
|
### Manuel
|
|
1. Démarrer `node server/index.mjs` et `npm run dev`
|
|
2. Ouvrir Sidebar → Trash
|
|
3. Vérifier que "old-folder" et "archive" s'affichent
|
|
4. Cliquer "old-folder" → Notes-liste doit montrer 2 notes
|
|
5. Vérifier badges: "old-folder (2)", "archive (1)"
|
|
6. Vérifier que `.trash` n'apparaît pas dans Folders
|
|
|
|
### E2E (à créer)
|
|
```typescript
|
|
test('Trash explorer displays folders and loads notes on click', async ({ page }) => {
|
|
await page.goto('http://localhost:3000');
|
|
await page.click('text=Trash');
|
|
await expect(page.locator('text=old-folder')).toBeVisible();
|
|
await page.click('text=old-folder');
|
|
await expect(page.locator('text=Old Note 2')).toBeVisible();
|
|
});
|
|
```
|
|
|
|
## Prochaines Améliorations (Optionnel)
|
|
|
|
1. **Factoriser TreeView**: `FileExplorerComponent`, `TrashExplorerComponent` et le child component partagent beaucoup de logique. Créer un composant `GenericTreeView` réutilisable.
|
|
|
|
2. **Actions sur Trash**: Ajouter boutons "Restore" / "Delete Permanently" dans le contexte menu.
|
|
|
|
3. **Empty State amélioré**: Ajouter une icône et un message plus descriptif quand .trash est vide.
|
|
|
|
4. **Performance**: Si `.trash` contient 1000+ fichiers, implémenter pagination lazy dans l'arbre.
|
|
|
|
## Notes Techniques
|
|
|
|
- **Signals Angular 20**: VaultService utilise computed signals pour réactivité
|
|
- **Path normalization**: Tous les paths utilisent '/' même sur Windows
|
|
- **Recursive folder counts**: `calculateTrashFolderCounts()` compte récursivement
|
|
- **Change detection**: OnPush utilisé partout pour performance
|