refactor(org): batch fetch child group entities

Signed-off-by: Carl-Erik Bergström <cbergstrom@spotify.com>

chore: add types to OwnershipCard

Signed-off-by: Carl-Erik Bergström <cbergstrom@spotify.com>
This commit is contained in:
Carl-Erik Bergström
2023-08-18 10:56:13 +02:00
parent 5a1ae618c0
commit 4bd4a134a0
6 changed files with 43 additions and 24 deletions
@@ -33,7 +33,8 @@ import {
import React from 'react';
import pluralize from 'pluralize';
import { catalogIndexRouteRef } from '../../../routes';
import { RelationType, useGetEntities } from './useGetEntities';
import { useGetEntities } from './useGetEntities';
import { RelationType } from './types';
const useStyles = makeStyles((theme: BackstageTheme) =>
createStyles({
@@ -27,9 +27,7 @@ import {
} from '@material-ui/core';
import React, { useState } from 'react';
import { ComponentsGrid } from './ComponentsGrid';
import { type RelationType, DefaultRelationType } from './useGetEntities';
export { type RelationType, DefaultRelationType } from './useGetEntities';
import { DefaultRelationType, RelationType } from './types';
const useStyles = makeStyles(theme => ({
list: {
@@ -14,3 +14,4 @@
* limitations under the License.
*/
export * from './OwnershipCard';
export * from './types';
@@ -0,0 +1,25 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** @public */
export const DefaultRelationType = {
Direct: 'direct',
Aggregated: 'aggregated',
} as const;
/** @public */
export type RelationType =
(typeof DefaultRelationType)[keyof typeof DefaultRelationType];
@@ -41,10 +41,12 @@ const givenUserEntity = {
},
} as Partial<Entity> as Entity;
const catalogApiMock: Pick<CatalogApi, 'getEntities' | 'getEntityByRef'> = {
const catalogApiMock: Pick<CatalogApi, 'getEntities' | 'getEntitiesByRefs'> = {
getEntities: jest.fn(async () => Promise.resolve({ items: [] })),
getEntityByRef: jest.fn(async ({ name }: CompoundEntityRef) =>
name === givenParentGroup ? givenParentGroupEntity : givenLeafGroupEntity,
getEntitiesByRefs: jest.fn(async ({ entityRefs: [ref] }) =>
ref.includes(givenParentGroup)
? { items: [givenParentGroupEntity] }
: { items: [givenLeafGroupEntity] },
),
};
@@ -31,6 +31,7 @@ import limiterFactory from 'p-limit';
import { useApi } from '@backstage/core-plugin-api';
import useAsync from 'react-use/lib/useAsync';
import qs from 'qs';
import { RelationType } from './types';
const limiter = limiterFactory(10);
@@ -92,13 +93,14 @@ const getChildOwnershipEntityRefs = async (
const hasChildGroups = childGroups.length > 0;
if (hasChildGroups) {
const childGroupEntities = (
await Promise.all(
childGroups.map(childGroup =>
limiter(() => catalogApi.getEntityByRef(childGroup)),
),
)
).filter(isEntity);
const entityRefs = childGroups.map(
({ kind, namespace, name }) => `${kind}:${namespace}/${name}`,
);
const childGroupResponse = await catalogApi.getEntitiesByRefs({
fields: ['kind', 'metadata.namespace', 'metadata.name'],
entityRefs,
});
const childGroupEntities = childGroupResponse.items.filter(isEntity);
return (
await Promise.all(
@@ -148,16 +150,6 @@ const getOwners = async (
return owners;
};
/** @public */
export const DefaultRelationType = {
Direct: 'direct',
Aggregated: 'aggregated',
} as const;
/** @public */
export type RelationType =
(typeof DefaultRelationType)[keyof typeof DefaultRelationType];
const getOwnedEntitiesByOwners = (
owners: string[],
kinds: string[],