228 lines
7.5 KiB
Markdown
228 lines
7.5 KiB
Markdown
# Implémentation de la fenêtre flottante des propriétés
|
|
|
|
## ✅ Modifications effectuées
|
|
|
|
### 1. Composant note-header (src/app/features/note/components/note-header/)
|
|
|
|
**Fichier TypeScript (`note-header.component.ts`):**
|
|
- ✅ Ajout des imports nécessaires: `Overlay`, `OverlayRef`, `ComponentPortal`, `PropertiesPopoverComponent`, `FrontmatterPropertiesService`, `VaultService`
|
|
- ✅ Ajout des propriétés pour gérer l'overlay:
|
|
- `popoverOpen`: booléen pour l'état d'ouverture
|
|
- `overlayRef`: référence à l'overlay CDK
|
|
- `closeTimer`: timer pour fermeture différée
|
|
- ✅ Injection des services nécessaires via `inject()`
|
|
- ✅ Méthodes ajoutées:
|
|
- `openPopover(origin: HTMLElement)`: ouvre le popover avec positionnement flexible
|
|
- `scheduleClose()`: fermeture différée (150ms)
|
|
- `togglePopover(origin: HTMLElement)`: bascule l'état
|
|
- `closePopover()`: ferme et nettoie l'overlay
|
|
- ✅ Nettoyage dans `ngOnDestroy()`
|
|
|
|
**Fichier HTML (`note-header.component.html`):**
|
|
- ✅ Ajout du bouton avec icône `list-tree` (SVG inline)
|
|
- ✅ Positionnement: juste après le bouton "Copier le chemin"
|
|
- ✅ Gestion des événements:
|
|
- `mouseenter` / `mouseleave`: hover desktop
|
|
- `focusin` / `focusout`: navigation clavier
|
|
- `click`: toggle mobile/desktop
|
|
- ✅ Attributs ARIA:
|
|
- `aria-label="Afficher les propriétés du document"`
|
|
- `aria-haspopup="dialog"`
|
|
- `[attr.aria-expanded]` dynamique
|
|
- `[attr.aria-controls]` conditionnel
|
|
|
|
### 2. Composants existants réutilisés
|
|
|
|
**PropertiesPopoverComponent** (`src/app/features/note/components/properties-popover/`)
|
|
- ✅ Déjà existant et fonctionnel
|
|
- ✅ Affiche toutes les propriétés du frontmatter YAML
|
|
- ✅ Sections: résumé, tags, aliases, états, propriétés additionnelles
|
|
- ✅ Empty state: "Aucune propriété détectée."
|
|
- ✅ Thème-aware avec classes Tailwind
|
|
|
|
**StateChipComponent** (`src/app/features/note/components/state-chip/`)
|
|
- ✅ Déjà existant
|
|
- ✅ Affiche les états avec icônes appropriées
|
|
- ✅ Gère: publish, favoris, archive, draft, private
|
|
|
|
**FrontmatterPropertiesService** (`src/app/features/note/shared/`)
|
|
- ✅ Service déjà implémenté
|
|
- ✅ Parse le YAML du frontmatter
|
|
- ✅ Normalise les propriétés
|
|
- ✅ Cache par noteId + timestamp
|
|
- ✅ Gère toutes les propriétés YAML disponibles
|
|
|
|
### 3. Suppression de l'ancienne section
|
|
|
|
**note-viewer.component.html:**
|
|
- ✅ Supprimé la section "Métadonnées" (lignes 16-28)
|
|
- ✅ Supprimé l'affichage en grille des propriétés frontmatter
|
|
|
|
**note-viewer.component.ts:**
|
|
- ✅ Supprimé la section `metadata-panel` du template inline (lignes 179-216)
|
|
- ✅ Supprimé les propriétés:
|
|
- `metadataExpanded`
|
|
- `maxMetadataPreviewItems`
|
|
- `metadataKeysToExclude`
|
|
- `dateFormatter` (utilisé uniquement pour metadata)
|
|
- ✅ Supprimé les computed signals:
|
|
- `metadataEntries`
|
|
- `metadataVisibleEntries`
|
|
- `metadataListId`
|
|
- ✅ Supprimé les méthodes:
|
|
- `toggleMetadataPanel()`
|
|
- `buildMetadataEntry()`
|
|
- `formatMetadataLabel()`
|
|
- `coerceToString()` → remplacé par `String()` dans `getAuthorFromFrontmatter()`
|
|
- `looksLikeEmail()`
|
|
- `looksLikeUrl()`
|
|
- `ensureUrlProtocol()`
|
|
- `looksLikeImageUrl()`
|
|
- `tryParseDate()`
|
|
- `isBooleanLike()`
|
|
- `translate()`
|
|
- `shouldSkipMetadataKey()`
|
|
- `slugify()`
|
|
- `getFrontmatterKeys()`
|
|
- ✅ Supprimé les types/interfaces:
|
|
- `MetadataEntryType`
|
|
- `MetadataEntry`
|
|
|
|
## 🎨 Fonctionnalités
|
|
|
|
### Déclenchement du popover
|
|
- **Desktop**: hover sur l'icône (mouseenter/mouseleave)
|
|
- **Clavier**: focus sur le bouton (focusin/focusout)
|
|
- **Mobile/Touch**: tap/click pour toggle
|
|
|
|
### Positionnement
|
|
- Position préférée: à droite de l'icône (8px offset)
|
|
- Position fallback: au-dessus de l'icône (8px offset)
|
|
- Repositionnement automatique avec `scrollStrategy`
|
|
|
|
### Contenu affiché
|
|
Le popover affiche **toutes** les propriétés YAML disponibles:
|
|
1. **Résumé** (si présent):
|
|
- Titre
|
|
- Auteur
|
|
- Date de création
|
|
- Date de modification
|
|
- Catégorie
|
|
|
|
2. **Tags** (badges avec border)
|
|
|
|
3. **Aliases** (séparés par " · ")
|
|
|
|
4. **États** (avec icônes):
|
|
- Publié (globe)
|
|
- Favori (heart)
|
|
- Archivé (archive/box)
|
|
- Brouillon (file)
|
|
- Privé (lock)
|
|
|
|
5. **Propriétés additionnelles**:
|
|
- Toutes les autres clés YAML non consommées
|
|
- Affichage avec label humanisé
|
|
- Support multiline pour texte long
|
|
|
|
### Thèmes
|
|
- ✅ Classes Tailwind theme-aware:
|
|
- `bg-popover`
|
|
- `text-popover-foreground`
|
|
- `border-border`
|
|
- ✅ Compatible thème clair/sombre
|
|
- ✅ Compatible thèmes personnalisés
|
|
|
|
### Accessibilité
|
|
- ✅ Navigation clavier complète
|
|
- ✅ Attributs ARIA appropriés
|
|
- ✅ Focus visible
|
|
- ✅ Rôle `dialog` sur le popover
|
|
|
|
## 🧪 Tests à effectuer
|
|
|
|
### Tests fonctionnels
|
|
- [ ] L'icône list-tree est visible dans le header
|
|
- [ ] L'icône est positionnée juste après le bouton "Copier"
|
|
- [ ] Hover desktop ouvre le popover
|
|
- [ ] Quitter le hover ferme le popover (avec délai)
|
|
- [ ] Click/tap toggle le popover
|
|
- [ ] Focus clavier ouvre le popover
|
|
- [ ] Blur clavier ferme le popover
|
|
- [ ] Click extérieur ferme le popover
|
|
|
|
### Tests de contenu
|
|
- [ ] Note avec toutes les propriétés → affichage complet
|
|
- [ ] Note sans frontmatter → "Aucune propriété détectée."
|
|
- [ ] Note avec propriétés partielles → seules les présentes sont affichées
|
|
- [ ] Tags nombreux → wrap correct sans overflow
|
|
- [ ] Propriétés additionnelles → affichage avec label humanisé
|
|
- [ ] États booléens → icônes et labels corrects
|
|
- [ ] Archive true → icône 🗃️ "Archivé"
|
|
- [ ] Archive false → icône 📋 "Non archivé"
|
|
|
|
### Tests thèmes
|
|
- [ ] Thème clair → lisible et cohérent
|
|
- [ ] Thème sombre → lisible et cohérent
|
|
- [ ] Thèmes personnalisés → couleurs héritées
|
|
|
|
### Tests responsive
|
|
- [ ] Desktop (>1024px) → hover fonctionne
|
|
- [ ] Tablet (768-1024px) → tap fonctionne
|
|
- [ ] Mobile (<768px) → tap fonctionne, taille adaptée
|
|
|
|
### Tests accessibilité
|
|
- [ ] Tab pour focus le bouton
|
|
- [ ] Enter/Space ouvre le popover
|
|
- [ ] Escape ferme le popover
|
|
- [ ] Lecteur d'écran annonce le bouton et son état
|
|
- [ ] Lecteur d'écran lit le contenu du popover
|
|
|
|
### Tests performance
|
|
- [ ] Première ouverture → parsing YAML
|
|
- [ ] Ouvertures suivantes → cache utilisé
|
|
- [ ] Changement de note → cache invalidé
|
|
- [ ] Pas de fuite mémoire après fermeture
|
|
|
|
## 📝 Notes techniques
|
|
|
|
### Pourquoi pas lucide-angular ?
|
|
- Lucide-angular n'est pas installé dans le projet
|
|
- Utilisation de SVG inline cohérente avec le reste du code
|
|
- Évite une dépendance supplémentaire
|
|
|
|
### Gestion du cache
|
|
Le service `FrontmatterPropertiesService` cache les propriétés par:
|
|
- `noteId` (clé primaire)
|
|
- `timestamp` (updatedAt ou mtime)
|
|
|
|
Le cache est automatiquement invalidé quand la note change.
|
|
|
|
### CDK Overlay
|
|
Configuration utilisée:
|
|
```typescript
|
|
{
|
|
positionStrategy: flexibleConnectedTo(origin)
|
|
.withPositions([right-start, top-start])
|
|
.withPush(true),
|
|
hasBackdrop: false,
|
|
scrollStrategy: reposition()
|
|
}
|
|
```
|
|
|
|
### Fermeture différée
|
|
Délai de 150ms pour permettre le passage de la souris entre le bouton et le popover sans fermeture intempestive.
|
|
|
|
## 🚀 Prochaines étapes
|
|
|
|
1. Tester manuellement toutes les fonctionnalités
|
|
2. Vérifier les thèmes clair/sombre
|
|
3. Tester sur mobile/tablet
|
|
4. Valider l'accessibilité clavier
|
|
5. Vérifier les performances (cache)
|
|
6. Créer des tests E2E si nécessaire
|
|
|
|
## ✨ Résultat
|
|
|
|
L'utilisateur dispose maintenant d'une interface moderne et accessible pour consulter toutes les propriétés YAML d'une note via une fenêtre flottante élégante, sans encombrer l'interface principale.
|