From 50be33b3cc0875837c9d54de0e994eb2aeb8260a Mon Sep 17 00:00:00 2001 From: Prasetya Aria Wibawa Date: Thu, 19 Aug 2021 16:44:38 +0700 Subject: [PATCH] pass through the owned list once and compute the counts at that time. Signed-off-by: Prasetya Aria Wibawa --- .../Cards/OwnershipCard/OwnershipCard.tsx | 106 ++++++++---------- 1 file changed, 49 insertions(+), 57 deletions(-) diff --git a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx index b9989d742b..51c39bfbe4 100644 --- a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx +++ b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx @@ -31,17 +31,25 @@ import { } from '@material-ui/core'; import React from 'react'; import { useAsync } from 'react-use'; - +import { generatePath } from 'react-router'; +import qs from 'qs'; import { InfoCard, InfoCardVariants, Progress, ResponseErrorPanel, } from '@backstage/core-components'; -import { useApi, configApiRef } from '@backstage/core-plugin-api'; +import { useApi } from '@backstage/core-plugin-api'; type BoxTypes = 'box1' | 'box2' | 'box3' | 'box4' | 'box5' | 'box6'; +type EntityTypeProps = { + name: string; + kind: string; + type: string; + count: number; +}; + const createPageTheme = ( theme: BackstageTheme, shapeKey: string, @@ -89,17 +97,6 @@ const useStyles = makeStyles((theme: BackstageTheme) => }), ); -const listEntitiesBy = (entities: Array, kind: string, type?: string) => - entities.filter( - e => e.kind === kind && (type ? e?.spec?.type === type : true), - ); - -const countEntitiesBy = ( - entities: Array, - kind: string, - type?: string, -) => listEntitiesBy(entities, kind, type).length; - const EntityCountTile = ({ counter, className, @@ -134,14 +131,20 @@ const EntityCountTile = ({ const getFilteredUrl = ( owner: Entity, - type: string, - entityKind: string, - baseUrl: string, + selectedEntity: EntityTypeProps, ): string => { const ownerName = owner.metadata.name; - const filteredUrl = ` - ${baseUrl}/catalog/?filters[kind]=${entityKind}&filters[type][0]=${type}&filters[user]=all&filters[owners][0]=${ownerName} - `; + const kind = selectedEntity.kind; + const type = selectedEntity.type; + const queryParams = qs.stringify({ + filters: { + kind, + type, + owners: ownerName, + user: 'all', + }, + }); + const filteredUrl = generatePath(`/catalog/?${queryParams}`); return filteredUrl; }; @@ -155,7 +158,6 @@ export const OwnershipCard = ({ }) => { const { entity } = useEntity(); const catalogApi = useApi(catalogApiRef); - const baseUrl = useApi(configApiRef).getString('app.baseUrl'); const { loading, @@ -180,47 +182,37 @@ export const OwnershipCard = ({ isOwnerOf(entity, component), ); - // Get key-value pair of Entity type and its kind - const entityKindObject = ownedEntitiesList.reduce((acc, ownedEntity) => { - if (typeof ownedEntity.spec?.type !== 'string') return acc; + const counts = ownedEntitiesList.reduce( + (acc: EntityTypeProps[], ownedEntity) => { + if (typeof ownedEntity.spec?.type !== 'string') return acc; - const entityType = ownedEntity.spec.type.toLocaleLowerCase('en-US'); - acc[entityType] = ownedEntity.kind; - return acc; - }, {} as Record); + const match = acc.find( + x => x.kind === ownedEntity.kind && x.type === ownedEntity.spec?.type, + ); + const name = ownedEntity.metadata.name; + if (match) { + match.count += 1; + } else { + acc.push({ + name, + kind: ownedEntity.kind, + type: ownedEntity.spec?.type?.toString(), + count: 1, + }); + } + return acc; + }, + [], + ); - // Sort by entity count descending, so the most common types appear on top - const countByType = ownedEntitiesList.reduce((acc, ownedEntity) => { - if (typeof ownedEntity.spec?.type !== 'string') return acc; + // Return top N (six) entities to be displayed in ownership boxes + const topN = counts.sort((a, b) => b.count - a.count).slice(0, 6); - const entityType = ownedEntity.spec.type.toLocaleLowerCase('en-US'); - if (!acc[entityType]) { - acc[entityType] = 0; - } - acc[entityType] += 1; - return acc; - }, {} as Record); - - // Get top 6 entity types to be displayed in OwnershipCard - const topSixEntityTypes = Object.entries(countByType) - .sort(([, count1], [, count2]) => count2 - count1) - .map(([type]) => type) - .slice(0, 6); - - return topSixEntityTypes.map((entityType, index) => ({ - counter: countEntitiesBy( - ownedEntitiesList, - entityKindObject[entityType], - entityType, - ), + return topN.map((topEntity, index) => ({ + counter: topEntity.count, className: `box${index + 1}`, - name: entityType.toLocaleUpperCase('en-US'), - url: getFilteredUrl( - entity, - entityType, - entityKindObject[entityType], - baseUrl, - ), + name: topEntity.type.toLocaleUpperCase('en-US'), + url: getFilteredUrl(entity, topEntity), })) as Array<{ counter: number; className: BoxTypes;