pass through the owned list once and compute the counts at that time.

Signed-off-by: Prasetya Aria Wibawa <prasetya.wibawa@grabtaxi.com>
This commit is contained in:
Prasetya Aria Wibawa
2021-08-19 16:44:38 +07:00
parent 8ab8c325cd
commit 50be33b3cc
@@ -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<Entity>, kind: string, type?: string) =>
entities.filter(
e => e.kind === kind && (type ? e?.spec?.type === type : true),
);
const countEntitiesBy = (
entities: Array<Entity>,
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<string, string>);
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<string, number>);
// 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;