diff --git a/assets/stylesheets/dashboard-theme.css b/assets/stylesheets/dashboard-theme.css index 21921fdb..b6a14bf1 100644 --- a/assets/stylesheets/dashboard-theme.css +++ b/assets/stylesheets/dashboard-theme.css @@ -77,3 +77,8 @@ body.ea-dark-scheme img.img-light { body:not(.ea-dark-scheme) img.img-dark { display: none; } + +.text-monospace { + font-family: var(--font-family-monospace); + font-size: 13px; +} diff --git a/src/Controller/Dashboard/DashboardPackagesInfoController.php b/src/Controller/Dashboard/DashboardPackagesInfoController.php index d2763a4a..138c2a03 100644 --- a/src/Controller/Dashboard/DashboardPackagesInfoController.php +++ b/src/Controller/Dashboard/DashboardPackagesInfoController.php @@ -4,7 +4,6 @@ use CodedMonkey\Dirigent\Attribute\IsGrantedAccess; use CodedMonkey\Dirigent\Attribute\MapPackage; -use CodedMonkey\Dirigent\Doctrine\Entity\Metadata; use CodedMonkey\Dirigent\Doctrine\Entity\Package; use CodedMonkey\Dirigent\Doctrine\Entity\PackageProvideLink; use CodedMonkey\Dirigent\Doctrine\Entity\PackageRequireLink; @@ -31,7 +30,7 @@ public function __construct( */ #[Route('/packages/{package}', name: 'dashboard_packages_info', requirements: ['package' => MapPackage::PACKAGE_REGEX])] #[IsGrantedAccess] - public function info(#[MapPackage] Package $package): Response + public function info(Request $request, #[MapPackage] Package $package, MetadataRepository $metadataRepository): Response { $version = $package->getLatestVersion(); @@ -39,16 +38,29 @@ public function info(#[MapPackage] Package $package): Response return $this->redirectToRoute('dashboard_packages_versions', ['package' => $package->getName()]); } - return $this->versionInfo($package, $version); + return $this->versionInfo($request, $package, $version, $metadataRepository); } #[Route('/packages/{package}/versions/{version}', name: 'dashboard_packages_version_info', requirements: ['package' => MapPackage::PACKAGE_REGEX, 'version' => '.*'])] #[IsGrantedAccess] - public function versionInfo(#[MapPackage] Package $package, #[MapPackage] Version $version): Response - { - /** @var MetadataRepository $metadataRepository */ - $metadataRepository = $this->entityManager->getRepository(Metadata::class); - $metadataRepository->fetchMetadataCollections($version->getCurrentMetadata()); + public function versionInfo( + Request $request, + #[MapPackage] Package $package, + #[MapPackage] Version $version, + MetadataRepository $metadataRepository, + ): Response { + $metadata = $version->getCurrentMetadata(); + $revision = $request->query->getInt('revision'); + if (0 !== $revision) { + $metadata = $metadataRepository->findOneBy(['version' => $version, 'revision' => $revision]); + } + if (null === $metadata) { + throw $this->createNotFoundException('The revision does not exist.'); + } + + $metadataRepository->fetchMetadataCollections($metadata); + + $metadataCount = $metadataRepository->getMetadataCountForVersion($version); $dependentCount = $this->entityManager->getRepository(PackageRequireLink::class)->count(['linkedPackageName' => $package->getName()]); $implementationCount = $this->entityManager->getRepository(PackageProvideLink::class)->count(['linkedPackageName' => $package->getName(), 'implementation' => true]); @@ -58,21 +70,40 @@ public function versionInfo(#[MapPackage] Package $package, #[MapPackage] Versio return $this->render('dashboard/packages/package_info.html.twig', [ 'package' => $package, 'version' => $version, - 'metadata' => $version->getCurrentMetadata(), + 'metadata' => $metadata, 'dependentCount' => $dependentCount, 'implementationCount' => $implementationCount, + 'metadataCount' => $metadataCount, 'providerCount' => $providerCount, 'suggesterCount' => $suggesterCount, ]); } + #[Route('/packages/{package}/revisions/{version}', name: 'dashboard_packages_version_metadata_list', requirements: ['package' => MapPackage::PACKAGE_REGEX, 'version' => '.*'])] + #[IsGrantedAccess] + public function versionMetadataList( + #[MapPackage] Package $package, + #[MapPackage] Version $version, + MetadataRepository $metadataRepository, + ): Response { + $metadataCollection = $metadataRepository->getMetadataCollectionForVersion($version); + + return $this->render('dashboard/packages/package_version_revisions.html.twig', [ + 'package' => $package, + 'version' => $version, + + 'metadataCollection' => $metadataCollection, + ]); + } + #[Route('/packages/{package}/versions', name: 'dashboard_packages_versions', requirements: ['package' => MapPackage::PACKAGE_REGEX])] #[IsGrantedAccess] - public function versions(#[MapPackage] Package $package): Response + public function versions(#[MapPackage] Package $package, MetadataRepository $metadataRepository): Response { return $this->render('dashboard/packages/package_versions.html.twig', [ 'package' => $package, + 'metadataCounts' => $metadataRepository->getMetadataCountsForPackage($package), ]); } diff --git a/src/Doctrine/Repository/MetadataRepository.php b/src/Doctrine/Repository/MetadataRepository.php index c1489785..d75239f3 100644 --- a/src/Doctrine/Repository/MetadataRepository.php +++ b/src/Doctrine/Repository/MetadataRepository.php @@ -3,8 +3,11 @@ namespace CodedMonkey\Dirigent\Doctrine\Repository; use CodedMonkey\Dirigent\Doctrine\Entity\Metadata; +use CodedMonkey\Dirigent\Doctrine\Entity\Package; +use CodedMonkey\Dirigent\Doctrine\Entity\Version; use CodedMonkey\Dirigent\Entity\MetadataLinkType; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\Common\Collections\Order; use Doctrine\Persistence\ManagerRegistry; /** @@ -40,6 +43,43 @@ public function remove(Metadata $entity, bool $flush = false): void } } + public function getMetadataCountForVersion(Version $version): int + { + return $this->count(['version' => $version]); + } + + public function getMetadataCollectionForVersion(Version $version): array + { + return $this->findBy( + ['version' => $version], + ['revision' => Order::Descending->value], + ); + } + + /** + * Returns a map of version ID => metadata count for all versions of the given package. + * + * @return array + */ + public function getMetadataCountsForPackage(Package $package): array + { + $rows = $this->createQueryBuilder('metadata') + ->select('IDENTITY(metadata.version) as version_id, COUNT(metadata.id) as revision_count') + ->join('metadata.version', 'version') + ->where('version.package = :package') + ->groupBy('metadata.version') + ->setParameter('package', $package) + ->getQuery() + ->getResult(); + + $counts = []; + foreach ($rows as $row) { + $counts[(int) $row['version_id']] = (int) $row['revision_count']; + } + + return $counts; + } + /** * Initializes all link and keyword collections for the given metadata. */ diff --git a/templates/dashboard/packages/_package_header.html.twig b/templates/dashboard/packages/_package_header.html.twig index d448e30d..958fbc4d 100644 --- a/templates/dashboard/packages/_package_header.html.twig +++ b/templates/dashboard/packages/_package_header.html.twig @@ -1,11 +1,15 @@ {% set currentPage = currentPage|default(null) %} +{% set currentVersion = currentVersion|default(null) %} {% set attrActive = 'class="nav-link active" aria-current="page"' %} {% set attr = 'class="nav-link text-primary"' %} -