From 7d31414008ce21f3947df00101f9a39020c60cdf Mon Sep 17 00:00:00 2001 From: Jyrki Keisala Date: Mon, 23 Dec 2024 10:38:23 +0200 Subject: [PATCH] refactor(ui): Use back-end queries for product statistics cards Similar to ORT runs, as the `...products/${productId}/statistics/runs` endpoint now returns - in addition to the item counts - also their distribution, switch to using the endpoint for the statistics cards, to render the product overview page faster. Signed-off-by: Jyrki Keisala --- .../product-issues-statistics-card.tsx | 19 +++++----- .../product-packages-statistics-card.tsx | 24 ++++++------- .../product-violations-statistics-card.tsx | 27 +++++++------- ...roduct-vulnerabilities-statistics-card.tsx | 36 +++++++++---------- 4 files changed, 50 insertions(+), 56 deletions(-) diff --git a/ui/src/routes/organizations/$orgId/products/$productId/-components/product-issues-statistics-card.tsx b/ui/src/routes/organizations/$orgId/products/$productId/-components/product-issues-statistics-card.tsx index bad09c3ff..87db3f879 100644 --- a/ui/src/routes/organizations/$orgId/products/$productId/-components/product-issues-statistics-card.tsx +++ b/ui/src/routes/organizations/$orgId/products/$productId/-components/product-issues-statistics-card.tsx @@ -19,10 +19,10 @@ import { Bug } from 'lucide-react'; +import { useProductsServiceGetOrtRunStatisticsByProductIdSuspense } from '@/api/queries/suspense'; +import { Severity } from '@/api/requests'; import { StatisticsCard } from '@/components/statistics-card'; import { getIssueSeverityBackgroundColor } from '@/helpers/get-status-class'; -import { calcIssueSeverityCounts } from '@/helpers/item-counts'; -import { useIssuesByProductIdSuspense } from '@/hooks/use-issues-by-product-suspense'; import { cn } from '@/lib/utils'; type ProductIssuesStatisticsCardProps = { @@ -34,23 +34,24 @@ export const ProductIssuesStatisticsCard = ({ productId, className, }: ProductIssuesStatisticsCardProps) => { - const data = useIssuesByProductIdSuspense({ + const data = useProductsServiceGetOrtRunStatisticsByProductIdSuspense({ productId: productId, }); - const issuesTotal = data.length; + const total = data.data.issuesCount; + const counts = data.data.issuesCountBySeverity; return ( } - value={issuesTotal} + value={total || '-'} counts={ - issuesTotal - ? calcIssueSeverityCounts(data).map(({ severity, count }) => ({ + counts + ? Object.entries(counts).map(([severity, count]) => ({ key: severity, - count, - color: getIssueSeverityBackgroundColor(severity), + count: count, + color: getIssueSeverityBackgroundColor(severity as Severity), })) : [] } diff --git a/ui/src/routes/organizations/$orgId/products/$productId/-components/product-packages-statistics-card.tsx b/ui/src/routes/organizations/$orgId/products/$productId/-components/product-packages-statistics-card.tsx index 67157e1ca..0e16baea5 100644 --- a/ui/src/routes/organizations/$orgId/products/$productId/-components/product-packages-statistics-card.tsx +++ b/ui/src/routes/organizations/$orgId/products/$productId/-components/product-packages-statistics-card.tsx @@ -19,10 +19,9 @@ import { Boxes } from 'lucide-react'; +import { useProductsServiceGetOrtRunStatisticsByProductIdSuspense } from '@/api/queries/suspense'; import { StatisticsCard } from '@/components/statistics-card'; import { getEcosystemBackgroundColor } from '@/helpers/get-status-class'; -import { calcPackageEcosystemCounts } from '@/helpers/item-counts'; -import { usePackagesByProductIdSuspense } from '@/hooks/use-packages-by-product-suspense'; import { cn } from '@/lib/utils'; type ProductPackagesStatisticsCardProps = { @@ -34,26 +33,23 @@ export const ProductPackagesStatisticsCard = ({ productId, className, }: ProductPackagesStatisticsCardProps) => { - const data = usePackagesByProductIdSuspense({ + const data = useProductsServiceGetOrtRunStatisticsByProductIdSuspense({ productId: productId, }); - const packagesTotal = data.length; + const total = data.data.packagesCount; + const counts = data.data.ecosystems; return ( } - value={packagesTotal} - counts={ - packagesTotal - ? calcPackageEcosystemCounts(data).map(({ ecosystem, count }) => ({ - key: ecosystem, - count, - color: getEcosystemBackgroundColor(ecosystem), - })) - : [] - } + value={total || '-'} + counts={counts?.map(({ name, count }) => ({ + key: name, + count: count, + color: getEcosystemBackgroundColor(name), + }))} className={cn('h-full hover:bg-muted/50', className)} /> ); diff --git a/ui/src/routes/organizations/$orgId/products/$productId/-components/product-violations-statistics-card.tsx b/ui/src/routes/organizations/$orgId/products/$productId/-components/product-violations-statistics-card.tsx index b65274c81..4abbe4079 100644 --- a/ui/src/routes/organizations/$orgId/products/$productId/-components/product-violations-statistics-card.tsx +++ b/ui/src/routes/organizations/$orgId/products/$productId/-components/product-violations-statistics-card.tsx @@ -19,10 +19,10 @@ import { Scale } from 'lucide-react'; +import { useProductsServiceGetOrtRunStatisticsByProductIdSuspense } from '@/api/queries/suspense'; +import { Severity } from '@/api/requests'; import { StatisticsCard } from '@/components/statistics-card'; import { getRuleViolationSeverityBackgroundColor } from '@/helpers/get-status-class'; -import { calcRuleViolationSeverityCounts } from '@/helpers/item-counts'; -import { useViolationsByProductIdSuspense } from '@/hooks/use-violations-by-product-suspense'; import { cn } from '@/lib/utils'; type ProductViolationsStatisticsCardProps = { @@ -34,26 +34,27 @@ export const ProductViolationsStatisticsCard = ({ productId, className, }: ProductViolationsStatisticsCardProps) => { - const data = useViolationsByProductIdSuspense({ + const data = useProductsServiceGetOrtRunStatisticsByProductIdSuspense({ productId: productId, }); - const violationsTotal = data.length; + const total = data.data.ruleViolationsCount; + const counts = data.data.ruleViolationsCountBySeverity; return ( } - value={violationsTotal} + value={total || '-'} counts={ - violationsTotal - ? calcRuleViolationSeverityCounts(data).map( - ({ severity, count }) => ({ - key: severity, - count, - color: getRuleViolationSeverityBackgroundColor(severity), - }) - ) + counts + ? Object.entries(counts).map(([severity, count]) => ({ + key: severity, + count: count, + color: getRuleViolationSeverityBackgroundColor( + severity as Severity + ), + })) : [] } className={cn('h-full hover:bg-muted/50', className)} diff --git a/ui/src/routes/organizations/$orgId/products/$productId/-components/product-vulnerabilities-statistics-card.tsx b/ui/src/routes/organizations/$orgId/products/$productId/-components/product-vulnerabilities-statistics-card.tsx index 95c490b1c..6431eca9f 100644 --- a/ui/src/routes/organizations/$orgId/products/$productId/-components/product-vulnerabilities-statistics-card.tsx +++ b/ui/src/routes/organizations/$orgId/products/$productId/-components/product-vulnerabilities-statistics-card.tsx @@ -19,11 +19,10 @@ import { ShieldQuestion } from 'lucide-react'; -import { useVulnerabilitiesServiceGetVulnerabilitiesAcrossRepositoriesByProductIdSuspense } from '@/api/queries/suspense'; +import { useProductsServiceGetOrtRunStatisticsByProductIdSuspense } from '@/api/queries/suspense'; +import { VulnerabilityRating } from '@/api/requests'; import { StatisticsCard } from '@/components/statistics-card'; import { getVulnerabilityRatingBackgroundColor } from '@/helpers/get-status-class'; -import { calcVulnerabilityRatingCounts } from '@/helpers/item-counts'; -import { ALL_ITEMS } from '@/lib/constants'; import { cn } from '@/lib/utils'; type ProductVulnerabilitiesStatisticsCardProps = { @@ -35,30 +34,27 @@ export const ProductVulnerabilitiesStatisticsCard = ({ productId, className, }: ProductVulnerabilitiesStatisticsCardProps) => { - const { data: vulnerabilities } = - useVulnerabilitiesServiceGetVulnerabilitiesAcrossRepositoriesByProductIdSuspense( - { - productId: productId, - limit: ALL_ITEMS, - } - ); + const data = useProductsServiceGetOrtRunStatisticsByProductIdSuspense({ + productId: productId, + }); - const total = vulnerabilities.pagination.totalCount; + const total = data.data.vulnerabilitiesCount; + const counts = data.data.vulnerabilitiesCountByRating; return ( } - value={total} + value={total || '-'} counts={ - total - ? calcVulnerabilityRatingCounts(vulnerabilities.data).map( - ({ rating, count }) => ({ - key: rating, - count, - color: getVulnerabilityRatingBackgroundColor(rating), - }) - ) + counts + ? Object.entries(counts).map(([rating, count]) => ({ + key: rating, + count: count, + color: getVulnerabilityRatingBackgroundColor( + rating as VulnerabilityRating + ), + })) : [] } className={cn('h-full hover:bg-muted/50', className)}