From 7fba3c6fcb1d92c983fc15639d79334c3c544661 Mon Sep 17 00:00:00 2001 From: "ext.jeremy.guillot@maxicoffee.domains" Date: Sat, 14 Mar 2026 00:45:29 +0100 Subject: [PATCH] chore: rattrapage --- .../app/domain/manga/domain/entities/manga.js | 8 +++++++- .../presentation/components/MangaCard.vue | 18 ++++------------- .../presentation/components/MangaGrid.vue | 2 +- .../components/MangaPreferredSourceCell.vue | 20 +++++++++++++++++++ .../pages/UserPreferencesPage.vue | 5 +++++ assets/vue/app/shared/i18n/locales/en.json | 3 ++- assets/vue/app/shared/i18n/locales/fr.json | 3 ++- .../QueryHandler/GetMangaListHandler.php | 12 ++++++++++- .../Response/MangaListResponse.php | 3 ++- .../Repository/MangaRepositoryInterface.php | 1 + .../ApiPlatform/Dto/MangaListItem.php | 3 +++ .../Provider/GetMangaListStateProvider.php | 12 ++++++++--- .../Persistence/LegacyMangaRepository.php | 12 +++++++++++ .../Manga/Adapter/InMemoryMangaRepository.php | 8 ++++++++ 14 files changed, 87 insertions(+), 23 deletions(-) create mode 100644 assets/vue/app/domain/manga/presentation/components/MangaPreferredSourceCell.vue diff --git a/assets/vue/app/domain/manga/domain/entities/manga.js b/assets/vue/app/domain/manga/domain/entities/manga.js index cba5686..78b1e3d 100644 --- a/assets/vue/app/domain/manga/domain/entities/manga.js +++ b/assets/vue/app/domain/manga/domain/entities/manga.js @@ -11,7 +11,10 @@ export class Manga { status = null, rating = null, genres = [], - createdAt = new Date().toISOString() + createdAt = new Date().toISOString(), + monitored = false, + chaptersTotal = 0, + chaptersScraped = 0, }) { this.id = id; this.slug = slug; @@ -25,6 +28,9 @@ export class Manga { this.rating = rating; this.genres = genres; this.createdAt = createdAt; + this.monitored = monitored; + this.chaptersTotal = chaptersTotal; + this.chaptersScraped = chaptersScraped; } static create(data) { diff --git a/assets/vue/app/domain/manga/presentation/components/MangaCard.vue b/assets/vue/app/domain/manga/presentation/components/MangaCard.vue index 1acdf6b..17ad77f 100644 --- a/assets/vue/app/domain/manga/presentation/components/MangaCard.vue +++ b/assets/vue/app/domain/manga/presentation/components/MangaCard.vue @@ -2,36 +2,26 @@ -
+
-

{{ manga.title }}

+

{{ manga.title }}

- {{ manga.publicationYear }} + {{ manga.publicationYear }}
-
Added: {{ formatDate(manga.createdAt) }}
diff --git a/assets/vue/app/domain/manga/presentation/components/MangaGrid.vue b/assets/vue/app/domain/manga/presentation/components/MangaGrid.vue index e991865..af72446 100644 --- a/assets/vue/app/domain/manga/presentation/components/MangaGrid.vue +++ b/assets/vue/app/domain/manga/presentation/components/MangaGrid.vue @@ -1,5 +1,5 @@ diff --git a/assets/vue/app/domain/manga/presentation/components/MangaPreferredSourceCell.vue b/assets/vue/app/domain/manga/presentation/components/MangaPreferredSourceCell.vue new file mode 100644 index 0000000..6fc3a42 --- /dev/null +++ b/assets/vue/app/domain/manga/presentation/components/MangaPreferredSourceCell.vue @@ -0,0 +1,20 @@ + + + diff --git a/assets/vue/app/domain/setting/presentation/pages/UserPreferencesPage.vue b/assets/vue/app/domain/setting/presentation/pages/UserPreferencesPage.vue index 172f314..d3b3181 100644 --- a/assets/vue/app/domain/setting/presentation/pages/UserPreferencesPage.vue +++ b/assets/vue/app/domain/setting/presentation/pages/UserPreferencesPage.vue @@ -64,6 +64,11 @@ @click="store.setDefaultView('list')"> {{ t('preferences.defaultView.list') }} +
diff --git a/assets/vue/app/shared/i18n/locales/en.json b/assets/vue/app/shared/i18n/locales/en.json index e3f03f8..5515730 100644 --- a/assets/vue/app/shared/i18n/locales/en.json +++ b/assets/vue/app/shared/i18n/locales/en.json @@ -27,7 +27,8 @@ "defaultView": { "label": "Default view", "grid": "Grid", - "list": "List" + "list": "List", + "table": "Table" }, "itemsPerPage": { "label": "Mangas per page" diff --git a/assets/vue/app/shared/i18n/locales/fr.json b/assets/vue/app/shared/i18n/locales/fr.json index f1c313c..ebeda64 100644 --- a/assets/vue/app/shared/i18n/locales/fr.json +++ b/assets/vue/app/shared/i18n/locales/fr.json @@ -27,7 +27,8 @@ "defaultView": { "label": "Vue par défaut", "grid": "Grille", - "list": "Liste" + "list": "Liste", + "table": "Tableau" }, "itemsPerPage": { "label": "Mangas par page" diff --git a/src/Domain/Manga/Application/QueryHandler/GetMangaListHandler.php b/src/Domain/Manga/Application/QueryHandler/GetMangaListHandler.php index 2af8af9..7f6648c 100644 --- a/src/Domain/Manga/Application/QueryHandler/GetMangaListHandler.php +++ b/src/Domain/Manga/Application/QueryHandler/GetMangaListHandler.php @@ -24,11 +24,21 @@ readonly class GetMangaListHandler $total = $this->mangaRepository->count(); + $chapterCounts = []; + foreach ($mangas as $manga) { + $id = $manga->getId()->getValue(); + $chapterCounts[$id] = [ + 'total' => $this->mangaRepository->countChapters($id), + 'scraped' => $this->mangaRepository->countAvailableChapters($id), + ]; + } + return new MangaListResponse( mangas: $mangas, total: $total, page: $query->page, - limit: $query->limit + limit: $query->limit, + chapterCounts: $chapterCounts ); } } diff --git a/src/Domain/Manga/Application/Response/MangaListResponse.php b/src/Domain/Manga/Application/Response/MangaListResponse.php index 26eec50..b5e2d6e 100644 --- a/src/Domain/Manga/Application/Response/MangaListResponse.php +++ b/src/Domain/Manga/Application/Response/MangaListResponse.php @@ -8,7 +8,8 @@ readonly class MangaListResponse public array $mangas, public int $total, public int $page, - public int $limit + public int $limit, + public array $chapterCounts = [] ) { } diff --git a/src/Domain/Manga/Domain/Contract/Repository/MangaRepositoryInterface.php b/src/Domain/Manga/Domain/Contract/Repository/MangaRepositoryInterface.php index e404043..d25a10d 100644 --- a/src/Domain/Manga/Domain/Contract/Repository/MangaRepositoryInterface.php +++ b/src/Domain/Manga/Domain/Contract/Repository/MangaRepositoryInterface.php @@ -31,6 +31,7 @@ interface MangaRepositoryInterface public function findChapters(string $mangaId, int $page = 1, int $limit = 20, string $sortOrder = 'desc'): array; public function countChapters(string $mangaId): int; + public function countAvailableChapters(string $mangaId): int; public function findChapterById(string $id): ?Chapter; public function findVisibleChapterById(string $id): ?Chapter; public function findChapterByMangaIdAndNumber(string $mangaId, float $chapterNumber): ?Chapter; diff --git a/src/Domain/Manga/Infrastructure/ApiPlatform/Dto/MangaListItem.php b/src/Domain/Manga/Infrastructure/ApiPlatform/Dto/MangaListItem.php index 91ae7ab..c8f6998 100644 --- a/src/Domain/Manga/Infrastructure/ApiPlatform/Dto/MangaListItem.php +++ b/src/Domain/Manga/Infrastructure/ApiPlatform/Dto/MangaListItem.php @@ -21,6 +21,9 @@ readonly class MangaListItem public string $status, public ?float $rating, public DateTimeImmutable $createdAt, + public bool $monitored = false, + public int $chaptersTotal = 0, + public int $chaptersScraped = 0, ) { } } diff --git a/src/Domain/Manga/Infrastructure/ApiPlatform/State/Provider/GetMangaListStateProvider.php b/src/Domain/Manga/Infrastructure/ApiPlatform/State/Provider/GetMangaListStateProvider.php index 9e092fe..35d6d22 100644 --- a/src/Domain/Manga/Infrastructure/ApiPlatform/State/Provider/GetMangaListStateProvider.php +++ b/src/Domain/Manga/Infrastructure/ApiPlatform/State/Provider/GetMangaListStateProvider.php @@ -29,7 +29,10 @@ readonly class GetMangaListStateProvider implements ProviderInterface return new MangaCollection( items: array_map( - fn (Manga $manga) => $this->createMangaListItem($manga), + fn (Manga $manga) => $this->createMangaListItem( + $manga, + $response->chapterCounts[$manga->getId()->getValue()] ?? [] + ), $response->mangas ), total: $response->total, @@ -40,7 +43,7 @@ readonly class GetMangaListStateProvider implements ProviderInterface ); } - private function createMangaListItem(Manga $manga): MangaListItem + private function createMangaListItem(Manga $manga, array $counts = []): MangaListItem { return new MangaListItem( id: $manga->getId()->getValue(), @@ -54,7 +57,10 @@ readonly class GetMangaListStateProvider implements ProviderInterface genres: $manga->getGenres(), status: $manga->getStatus(), rating: $manga->getRating(), - createdAt: $manga->getCreatedAt() + createdAt: $manga->getCreatedAt(), + monitored: $manga->getMonitoringStatus()->isEnabled(), + chaptersTotal: $counts['total'] ?? 0, + chaptersScraped: $counts['scraped'] ?? 0, ); } } diff --git a/src/Domain/Manga/Infrastructure/Persistence/LegacyMangaRepository.php b/src/Domain/Manga/Infrastructure/Persistence/LegacyMangaRepository.php index 5ab77ac..2cc45b0 100644 --- a/src/Domain/Manga/Infrastructure/Persistence/LegacyMangaRepository.php +++ b/src/Domain/Manga/Infrastructure/Persistence/LegacyMangaRepository.php @@ -196,6 +196,18 @@ readonly class LegacyMangaRepository implements MangaRepositoryInterface ->getSingleScalarResult(); } + public function countAvailableChapters(string $mangaId): int + { + return $this->entityManager->createQueryBuilder() + ->select('COUNT(c.id)') + ->from(EntityChapter::class, 'c') + ->where('c.manga = :mangaId') + ->andWhere('c.pagesDirectory IS NOT NULL OR c.cbzPath IS NOT NULL') + ->setParameter('mangaId', $mangaId) + ->getQuery() + ->getSingleScalarResult(); + } + public function findByExternalId(ExternalId $externalId): ?DomainManga { $entity = $this->entityManager->getRepository(EntityManga::class)->findOneBy([ diff --git a/tests/Domain/Manga/Adapter/InMemoryMangaRepository.php b/tests/Domain/Manga/Adapter/InMemoryMangaRepository.php index 6174506..9eeb88c 100644 --- a/tests/Domain/Manga/Adapter/InMemoryMangaRepository.php +++ b/tests/Domain/Manga/Adapter/InMemoryMangaRepository.php @@ -135,6 +135,14 @@ class InMemoryMangaRepository implements MangaRepositoryInterface return count($this->chapters[$mangaId] ?? []); } + public function countAvailableChapters(string $mangaId): int + { + return count(array_filter( + $this->chapters[$mangaId] ?? [], + fn (Chapter $c) => $c->isAvailable() + )); + } + public function findChapterById(string $id): ?Chapter { return $this->chaptersById[$id] ?? null; -- 2.49.1