Merge pull request 'style/sidebar-cleanup-and-ui-polish' (#9) from style/sidebar-cleanup-and-ui-polish into main
Some checks failed
Deploy / deploy (push) Failing after 1m54s

Reviewed-on: #9
This commit was merged in pull request #9.
This commit is contained in:
2026-03-14 00:37:29 +01:00
6 changed files with 149 additions and 31 deletions

29
DONE.md Normal file
View File

@@ -0,0 +1,29 @@
# DONE.md — Tâches terminées
## [UI] Passe sur le menu latéral (Sidebar) — 2026-03-14
> Branche : `style/sidebar-cleanup-and-ui-polish` | Commit : `d219ed1`
- [x] **`isActive` incorrect** : inclut désormais les sous-items dans le calcul (groupe Mangas actif sur `/import`)
- [x] **Double déclenchement toggle/navigation** : chevron déplacé dans un `<button>` séparé du `RouterLink`
- [x] **Parent items** (`MenuGroup.vue`) : ajout `hover:text-white` aligné avec le style SubMenuItem
- [x] **SubMenuItems** (`SubMenuItem.vue`) : ajout `hover:bg-gray-700` pour harmoniser avec le parent
- [x] **État actif vs hover** : logique couleur unifiée sur les deux niveaux
## [UI] Supprimer "Calendrier" du menu — 2026-03-14
> Branche : `style/sidebar-cleanup-and-ui-polish` | Commit : `d219ed1`
- [x] Retirer l'entrée "Calendrier" de la Sidebar
- [x] Supprimer la route Vue Router `/calendar`
---
## [UI] Simplifier l'affichage table de la HomePage — 2026-03-14
> Branche : `style/simplifier-table-homepage` | Commit : `cc27fc4`
- [x] Supprimer le wrapper card (`bg-white shadow rounded-lg overflow-hidden`) — remplacer par un simple `border-t`
- [x] Lien du titre : passer le hover de bleu (`hover:text-blue-600`) à vert (`hover:text-green-500`)
- [x] Icône monitoring : remplacer `BellIcon` / `BellSlashIcon` par `BookmarkIcon` / `BookmarkSlashIcon`
- [x] Supprimer le padding du wrapper + `container mx-auto` pour tableau pleine largeur

101
TASK.md Normal file
View File

@@ -0,0 +1,101 @@
# TASK.md — Tâches à venir
## [Feature] Découvrir — Suggestions de mangas via MangaDex
**Objectif :** Page "Découvrir" qui propose des mangas populaires/récents depuis l'API MangaDex, en excluant ceux déjà présents en base (comparaison via `externalId` = ID MangaDex).
### Backend
- [ ] **Consulter la doc API MangaDex** pour identifier le(s) endpoint(s) pertinents (mangas populaires, récemment mis à jour, tendances…) et les paramètres disponibles (filtres langue, statut, contentRating, etc.)
- [ ] **Étendre le client MangaDex existant** pour exposer le(s) nouvel(aux) endpoint(s) identifiés (nouveau(x) méthode(s) dans le client + adapter le contrat d'interface si besoin)
- [ ] Query `GetDiscoverMangaListQuery` + handler qui appelle le client MangaDex et filtre les résultats dont l'`externalId` est déjà en base
- [ ] Response DTO `DiscoverMangaListResponse` avec les champs nécessaires à l'affichage (id MangaDex, titre, couverture, genres, statut…)
- [ ] State Provider API Platform sur la route `GET /api/manga/discover`
### Frontend
- [ ] Page `DiscoverPage.vue` avec grille de cards (réutiliser `MangaCard.vue` ou créer `DiscoverMangaCard.vue`)
- [ ] Composable TanStack Query `useDiscoverMangaList`
- [ ] Route Vue Router `/discover`
- [ ] Entrée dans la Sidebar
---
## [Domain] Créer le domaine "System"
**Objectif :** Poser la structure DDD hexagonale du nouveau domaine `System` qui servira de socle aux fonctionnalités Status et Logs.
- [ ] Créer l'arborescence `src/Domain/System/Domain/`, `Application/`, `Infrastructure/`
- [ ] Créer l'arborescence frontend `assets/vue/app/domain/system/`
- [ ] Vérifier la conformité avec `phparkitect.php` (ajouter le domaine si nécessaire)
---
## [Feature] System — Page "Status"
**Objectif :** Page de monitoring affichant l'état général de l'application.
### Backend
- [ ] Query `GetSystemStatusQuery` + handler qui agrège :
- Version de l'application (depuis `composer.json` ou variable d'env)
- Statut des services critiques (base de données, Messenger workers, stockage)
- Poids total des images (scan du dossier `IMAGE_DATA_PATH`)
- Poids total des CBZ (scan du dossier `MANGA_DATA_PATH`)
- Liens / chemins vers les dossiers de stockage configurés
- [ ] Response DTO `SystemStatusResponse`
- [ ] State Provider API Platform sur la route `GET /api/system/status`
### Frontend
- [ ] Page `StatusPage.vue` avec sections (Général, Stockage, Services)
- [ ] Composable TanStack Query `useSystemStatus`
- [ ] Route Vue Router `/system/status`
---
## [Feature] System — Page "Logs"
**Objectif :** Page de consultation des logs d'erreur des workers Messenger, avec filtres.
### Backend
- [ ] Définir le contrat `WorkerLogRepositoryInterface` dans `System/Domain/Contract/Repository/`
- [ ] Implémenter `DoctrineWorkerLogRepository` (ou lecture des logs Monolog selon la stratégie retenue) dans `Infrastructure/`
- [ ] Query `GetWorkerLogsQuery` avec paramètres de filtrage (date début/fin, source, niveau, worker/transport) + handler
- [ ] Response DTO `WorkerLogListResponse` (liste paginée)
- [ ] State Provider API Platform sur la route `GET /api/system/logs`
### Frontend
- [ ] Page `LogsPage.vue` avec tableau paginé + panneau de filtres
- [ ] Filtres disponibles : plage de dates, source (transport Messenger), niveau d'erreur, manga associé (source préférée)
- [ ] Composable TanStack Query `useWorkerLogs` (avec paramètres de filtre réactifs)
- [ ] Route Vue Router `/system/logs`
---
## [UI] Simplifier l'affichage overview des mangas
**Objectif :** Améliorer l'ergonomie de la page d'accueil mangas en simplifiant l'affichage et en ajoutant des raccourcis rapides vers les actions courantes.
### Vue table
- [ ] **Raccourcis actions rapides** : dans chaque ligne de la table, ajouter un menu d'actions (icônes ou dropdown) permettant d'ouvrir directement les modales : éditer le manga, gérer les sources, lancer un scrape, supprimer
- [ ] **Colonne statut de lecture** : afficher le statut (en cours / terminé / abandonné…) directement dans la ligne sans ouvrir la modale
- [ ] **Colonne dernière activité** : date du dernier chapitre scrapé ou lu
- [ ] **Raccourci ouverture rapide** : clic sur le titre ouvre le reader / detail page directement
### Vue grille (MangaCard)
- [ ] **Overlay actions** : au survol d'une card, afficher des boutons d'action rapide superposés (éditer, sources, scrape)
- [ ] **Badge statut source préférée** : indicateur visuel si la source préférée est configurée ou non
### Modales accessibles
- [ ] **Modale "Éditer manga"** : accessible depuis la table (icône crayon) et la card (overlay)
- [ ] **Modale "Gérer sources"** : accessible depuis la table et la card
- [ ] **Confirmation scrape rapide** : déclencher un scrape depuis la liste sans naviguer vers le détail
---

View File

@@ -82,12 +82,6 @@ const routes = [
name: 'convert',
component: ConversionPage
},
{
path: '/calendar',
name: 'calendar',
component: PlaceholderComponent,
props: { title: 'Calendrier' }
},
{
path: '/activity',
name: 'activity',

View File

@@ -27,7 +27,6 @@
ArrowDownTrayIcon,
ArrowsRightLeftIcon,
BookOpenIcon,
CalendarIcon,
ClockIcon,
Cog6ToothIcon,
ComputerDesktopIcon,
@@ -69,12 +68,6 @@ import MenuGroup from './sidebar/MenuGroup.vue';
to: '/convert',
id: 'convert'
},
{
icon: CalendarIcon,
text: 'Calendrier',
to: '/calendar',
id: 'calendar'
},
{
icon: ClockIcon,
text: 'Activité',

View File

@@ -3,24 +3,25 @@
class="border-l-4"
:class="{
'border-green-600': isActive,
'hover:bg-gray-700 border-transparent': !isActive
'border-transparent': !isActive
}">
<div class="flex w-full" @click="toggleExpanded">
<div class="flex w-full">
<RouterLink
:to="to"
class="flex-grow px-4 py-2 flex items-center"
:class="{
'text-green-600 bg-gray-800': isActive
}">
<div class="flex items-center flex-grow">
<component :is="icon" class="w-5 h-5 mr-3" />
<span class="px-2">{{ text }}</span>
</div>
<component
v-if="subItems.length > 0"
:is="expanded ? ChevronUpIcon : ChevronDownIcon"
class="w-4 h-4" />
:class="isActive
? 'text-green-600 bg-gray-800'
: 'hover:bg-gray-700 hover:text-white'">
<component :is="icon" class="w-5 h-5 mr-3" />
<span class="px-2">{{ text }}</span>
</RouterLink>
<button
v-if="subItems.length > 0"
class="px-3 hover:bg-gray-700"
:class="isActive ? 'text-green-600 bg-gray-800' : 'hover:text-white'"
@click="toggleExpanded">
<component :is="expanded ? ChevronUpIcon : ChevronDownIcon" class="w-4 h-4" />
</button>
</div>
<ul v-if="subItems.length > 0" class="ml-8 mt-2 space-y-4" v-show="expanded">
@@ -71,14 +72,14 @@
const isActive = computed(() => {
if (!props.to) {
return props.subItems?.some(subItem => route.path === subItem.to) || false;
return props.subItems?.some(subItem => route.path.startsWith(subItem.to)) || false;
}
if (props.to === '/') {
return route.path === props.to || props.subItems.map(item => item.to).includes(route.path);
return route.path === props.to || props.subItems.some(item => route.path.startsWith(item.to));
}
return route.path.startsWith(props.to);
return route.path.startsWith(props.to) || props.subItems.some(item => route.path.startsWith(item.to));
});
const isRouteMatching = path => {

View File

@@ -1,9 +1,9 @@
<template>
<li>
<RouterLink v-if="to" :to="to" class="block hover:text-green-600" role="menuitem">
<RouterLink v-if="to" :to="to" class="block px-2 py-1 rounded hover:bg-gray-700 hover:text-white" role="menuitem">
{{ text }}
</RouterLink>
<button v-else @click="$emit('click')" class="w-full text-left hover:text-green-600" role="menuitem">
<button v-else @click="$emit('click')" class="w-full text-left px-2 py-1 rounded hover:bg-gray-700 hover:text-white" role="menuitem">
{{ text }}
</button>
</li>