- Replace welcome message with a professional dashboard widget displaying the last opened files. - Implement configurable file limit via existing settings. - Design includes responsive grid layout and various UI states (loading, empty, error). - Introduce new JavaScript module `DashboardRecentWidget` for handling file loading and rendering. - Ensure accessibility compliance and responsive design breakpoints.
162 lines
5.0 KiB
Markdown
162 lines
5.0 KiB
Markdown
# SPEC: Widget "Derniers fichiers ouverts" sur la page principale
|
|
|
|
## 1. Objectif
|
|
|
|
Remplacer le message d'accueil actuel (`#welcome`) par un widget dashboard professionnel affichant les **XX derniers fichiers ouverts**. Le nombre de fichiers affichés sera configurable via les paramètres existants (`cfg-recent-limit`).
|
|
|
|
## 2. Architecture du composant
|
|
|
|
```mermaid
|
|
graph TD
|
|
A["#content-area"] --> B["#dashboard-home"]
|
|
B --> C["En-tête: Logo + Titre"]
|
|
B --> D["Sélecteur vault filter"]
|
|
B --> E["#dashboard-recent-grid"]
|
|
B --> F["#dashboard-recent-empty"]
|
|
|
|
E --> G["Carte 1: fichier récent"]
|
|
E --> H["Carte 2: fichier récent"]
|
|
E --> I["..."]
|
|
|
|
G --> G1["Icône fichier"]
|
|
G --> G2["Titre"]
|
|
G --> G3["Chemin breadcrumb"]
|
|
G --> G4["Tags"]
|
|
G --> G5["Horodatage"]
|
|
```
|
|
|
|
## 3. Design UI/UX
|
|
|
|
### 3.1 Structure HTML (dans `#content-area`)
|
|
|
|
```html
|
|
<div id="dashboard-home" class="dashboard-home">
|
|
<div class="dashboard-header">
|
|
<div class="dashboard-title-row">
|
|
<i data-lucide="clock" class="dashboard-icon"></i>
|
|
<h2>Derniers fichiers ouverts</h2>
|
|
</div>
|
|
<div class="dashboard-filter-row">
|
|
<select id="dashboard-vault-filter">
|
|
<option value="">Tous les vaults</option>
|
|
</select>
|
|
<span class="dashboard-count" id="dashboard-count"></span>
|
|
</div>
|
|
</div>
|
|
<div id="dashboard-recent-grid" class="dashboard-recent-grid"></div>
|
|
<div id="dashboard-recent-empty" class="dashboard-recent-empty hidden">
|
|
<i data-lucide="inbox"></i>
|
|
<span>Aucun fichier récent</span>
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
### 3.2 Layout Grid
|
|
|
|
- **Desktop (>1024px)**: Grid 3 colonnes
|
|
- **Tablet (768-1024px)**: Grid 2 colonnes
|
|
- **Mobile (<768px)**: Grid 1 colonne
|
|
|
|
### 3.3 Style des cartes (`.dashboard-card`)
|
|
|
|
| Élément | Style |
|
|
|---------|-------|
|
|
| Container | `border-radius: 12px`, `padding: 16px`, fond `var(--bg-secondary)` |
|
|
| Hover | Légère élévation avec `box-shadow`, bordure accent |
|
|
| Icône | 32x32px, couleur accent |
|
|
| Titre | `font-weight: 600`, `font-size: 14px`, truncation avec ellipsis |
|
|
| Chemin | `font-size: 11px`, `color: var(--text-muted)` |
|
|
| Tags | Pills compacts, même style que sidebar |
|
|
| Horodatage | Badge discret avec icône clock |
|
|
| Badge vault | Position absolute en haut-droit |
|
|
|
|
### 3.4 États
|
|
|
|
| État | Description |
|
|
|------|-------------|
|
|
| **Chargement** | Skeleton cards animées (pulse) |
|
|
| **Données** | Grid de cartes |
|
|
| **Vide** | Icône + message centré |
|
|
| **Erreur** | Toast notification |
|
|
|
|
## 4. Interactions
|
|
|
|
| Action | Comportement |
|
|
|--------|--------------|
|
|
| **Clic sur carte** | Ouvre le fichier (`openFile(vault, path)`) |
|
|
| **Changement filter vault** | Recharge les données avec filtre |
|
|
| **Hover carte** | Élévation visuelle, curseur pointer |
|
|
| **Fermeture fichier** | Affiche le dashboard (si plus de fichier ouvert) |
|
|
|
|
## 5. Intégration JavaScript
|
|
|
|
### 5.1 Nouveau module `DashboardRecentWidget`
|
|
|
|
```javascript
|
|
const DashboardRecentWidget = {
|
|
async load(vaultFilter) { /* Charge via /api/recent */ },
|
|
render(files) { /* Génère le HTML des cartes */ },
|
|
showEmpty() { /* Affiche état vide */ },
|
|
showLoading() { /* Affiche skeletons */ },
|
|
init() { /* Bind events, charge initial */ }
|
|
};
|
|
```
|
|
|
|
### 5.2 Points d'intégration
|
|
|
|
- **Au démarrage**: `DashboardRecentWidget.init()` dans `DOMContentLoaded`
|
|
- **Ouverture fichier**: Dashboard masqué automatiquement
|
|
- **Fermeture fichier**: Dashboard affiché si `activeEditor === null`
|
|
- **Filtre vault**: Recharge via `loadRecentFiles` de la sidebar (partage du cache)
|
|
|
|
### 5.3 Partage avec sidebar "Recent"
|
|
|
|
Le widget réutilisera `_recentFilesCache` et `renderRecentList` mais avec un **template de carte différent** pour le dashboard.
|
|
|
|
## 6. Fichiers à modifier
|
|
|
|
| Fichier | Modification |
|
|
|---------|--------------|
|
|
| `frontend/index.html` | Remplacer `#welcome` par `#dashboard-home` |
|
|
| `frontend/style.css` | Ajouter `.dashboard-home`, `.dashboard-card`, skeleton, animations |
|
|
| `frontend/app.js` | Ajouter `DashboardRecentWidget`, modifier `showWelcome()`, intégration hooks |
|
|
|
|
## 7. Paramètres configurables
|
|
|
|
| Paramètre | Source | Description |
|
|
|-----------|--------|-------------|
|
|
| `recent_files_limit` | Backend config | Nombre max de fichiers (5-100, défaut: 20) |
|
|
|
|
## 8. Accessibilité
|
|
|
|
- Rôles ARIA appropriés (`role="region"`, `aria-label`)
|
|
- Navigation clavier fonctionnelle
|
|
- Contraste des couleurs conforme WCAG 2.1 AA
|
|
- Support screen reader pour les états vides/chargement
|
|
|
|
## 9. Responsive breakpoints
|
|
|
|
```css
|
|
.dashboard-recent-grid {
|
|
display: grid;
|
|
gap: 16px;
|
|
/* Mobile first */
|
|
grid-template-columns: 1fr;
|
|
}
|
|
@media (min-width: 768px) {
|
|
grid-template-columns: repeat(2, 1fr);
|
|
}
|
|
@media (min-width: 1024px) {
|
|
grid-template-columns: repeat(3, 1fr);
|
|
}
|
|
```
|
|
|
|
## 10. Animations
|
|
|
|
| Événement | Animation |
|
|
|-----------|-----------|
|
|
| Entrée cartes | Fade-in + slide-up staggeré (50ms entre cartes) |
|
|
| Hover carte | Scale 1.02 + shadow |
|
|
| Skeleton loading | Pulse animation |
|
|
| Transition vault filter | Fade out/in des cartes |
|