From a8331830f1b4d3efbb8bece749d56041c6b732f0 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 21 Feb 2022 10:09:49 +0100 Subject: [PATCH] catalog-react: deprecate useEntityKinds Signed-off-by: Johan Haals --- .changeset/fast-clouds-add.md | 5 + .changeset/five-geese-beam.md | 6 + .../SelectedKindsFilter.test.tsx | 105 +++++++++--------- .../CatalogGraphPage/SelectedKindsFilter.tsx | 11 +- .../catalog-react/src/hooks/useEntityKinds.ts | 1 + .../CatalogKindHeader.test.tsx | 40 ++++--- .../CatalogKindHeader/CatalogKindHeader.tsx | 13 ++- 7 files changed, 109 insertions(+), 72 deletions(-) create mode 100644 .changeset/fast-clouds-add.md create mode 100644 .changeset/five-geese-beam.md diff --git a/.changeset/fast-clouds-add.md b/.changeset/fast-clouds-add.md new file mode 100644 index 0000000000..e407e716d5 --- /dev/null +++ b/.changeset/fast-clouds-add.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Deprecated the `useEntityKinds` hook due to low usage and utility value. diff --git a/.changeset/five-geese-beam.md b/.changeset/five-geese-beam.md new file mode 100644 index 0000000000..0a3c66931a --- /dev/null +++ b/.changeset/five-geese-beam.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-catalog': patch +'@backstage/plugin-catalog-graph': patch +--- + +Remove use of deprecated `useEntityKinds` hook. diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedKindsFilter.test.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedKindsFilter.test.tsx index c98c77c975..5ac5bc5a5f 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedKindsFilter.test.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedKindsFilter.test.tsx @@ -13,63 +13,63 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { useApi as useApiMocked } from '@backstage/core-plugin-api'; -import { useEntityKinds as useEntityKindsMocked } from '@backstage/plugin-catalog-react'; -import { render, waitFor } from '@testing-library/react'; +import { GetEntityFacetsResponse } from '@backstage/catalog-client'; +import { ApiProvider } from '@backstage/core-app-api'; +import { AlertApi, alertApiRef } from '@backstage/core-plugin-api'; +import { catalogApiRef } from '@backstage/plugin-catalog-react'; +import { renderWithEffects, TestApiRegistry } from '@backstage/test-utils'; +import { waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; import { SelectedKindsFilter } from './SelectedKindsFilter'; -jest.mock('@backstage/core-plugin-api'); -jest.mock('@backstage/plugin-catalog-react'); - -const useApi = useApiMocked as jest.Mock>; -const useEntityKinds = useEntityKindsMocked as jest.Mock< - ReturnType ->; +const catalogApi = { + getEntityFacets: jest.fn().mockResolvedValue({ + facets: { + kind: [ + { value: 'Component', count: 2 }, + { value: 'System', count: 1 }, + { value: 'API', count: 1 }, + { value: 'Resource', count: 1 }, + ], + }, + } as GetEntityFacetsResponse), +}; +const apis = TestApiRegistry.from( + [catalogApiRef, catalogApi], + [alertApiRef, {} as AlertApi], +); describe('', () => { - beforeEach(() => { - useApi.mockReturnValue({}); - useEntityKinds.mockReturnValue({ - loading: false, - kinds: ['API', 'Component', 'System', 'Domain', 'Resource'], - error: undefined, - }); + it('should not explode while loading', async () => { + const rendered = await renderWithEffects( + + {}} /> + , + ); + expect(rendered.baseElement).toBeInTheDocument(); }); - afterEach(() => jest.resetAllMocks()); - - test('should not explode while loading', () => { - useEntityKinds.mockReturnValue({ - loading: true, - kinds: undefined, - error: undefined, - }); - const { baseElement } = render( - {}} />, + it('should render current value', async () => { + const rendered = await renderWithEffects( + + {}} /> + , ); - expect(baseElement).toBeInTheDocument(); + expect(rendered.getByText('API')).toBeInTheDocument(); + expect(rendered.getByText('Component')).toBeInTheDocument(); }); - test('should render current value', () => { - const { getByText } = render( - {}} />, - ); - - expect(getByText('API')).toBeInTheDocument(); - expect(getByText('Component')).toBeInTheDocument(); - }); - - test('should select value', async () => { + it('should select value', async () => { const onChange = jest.fn(); - const { getByText, getByLabelText } = render( - , + const { getByLabelText, getByText } = await renderWithEffects( + + + , ); userEvent.click(getByLabelText('Open')); - await waitFor(() => expect(getByText('System')).toBeInTheDocument()); userEvent.click(getByText('System')); @@ -79,15 +79,16 @@ describe('', () => { }); }); - test('should return undefined if all values are selected', async () => { + it('should return undefined if all values are selected', async () => { const onChange = jest.fn(); - const { getByText, getByLabelText } = render( - , + const { getByLabelText, getByText } = await renderWithEffects( + + + , ); - userEvent.click(getByLabelText('Open')); await waitFor(() => expect(getByText('Resource')).toBeInTheDocument()); @@ -99,10 +100,12 @@ describe('', () => { }); }); - test('should return all values when cleared', async () => { + it('should return all values when cleared', async () => { const onChange = jest.fn(); - const { getByRole } = render( - , + const { getByRole } = await renderWithEffects( + + + , ); userEvent.click(getByRole('combobox')); diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedKindsFilter.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedKindsFilter.tsx index 87ba8e77bf..316f83da62 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedKindsFilter.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedKindsFilter.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ import { alertApiRef, useApi } from '@backstage/core-plugin-api'; -import { useEntityKinds } from '@backstage/plugin-catalog-react'; +import { catalogApiRef } from '@backstage/plugin-catalog-react'; import { Box, Checkbox, @@ -28,6 +28,7 @@ import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import { Autocomplete } from '@material-ui/lab'; import React, { useCallback, useEffect, useMemo } from 'react'; +import useAsync from 'react-use/lib/useAsync'; const useStyles = makeStyles({ formControl: { @@ -43,7 +44,13 @@ export type Props = { export const SelectedKindsFilter = ({ value, onChange }: Props) => { const classes = useStyles(); const alertApi = useApi(alertApiRef); - const { error, kinds } = useEntityKinds(); + const catalogApi = useApi(catalogApiRef); + + const { error, value: kinds } = useAsync(async () => { + return await catalogApi + .getEntityFacets({ facets: ['kind'] }) + .then(response => response.facets.kind?.map(f => f.value).sort() || []); + }); useEffect(() => { if (error) { diff --git a/plugins/catalog-react/src/hooks/useEntityKinds.ts b/plugins/catalog-react/src/hooks/useEntityKinds.ts index 5fad49df8e..3dfc31eb88 100644 --- a/plugins/catalog-react/src/hooks/useEntityKinds.ts +++ b/plugins/catalog-react/src/hooks/useEntityKinds.ts @@ -21,6 +21,7 @@ import { catalogApiRef } from '../api'; /** * Retrieve a list of unique entity kinds present in the catalog * @public + * @deprecated and will be removed due to low utility value. */ export function useEntityKinds() { const catalogApi = useApi(catalogApiRef); diff --git a/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.test.tsx b/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.test.tsx index 795d57df47..45d42d0ea6 100644 --- a/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.test.tsx +++ b/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.test.tsx @@ -24,8 +24,13 @@ import { MockEntityListContextProvider, } from '@backstage/plugin-catalog-react'; import { ApiProvider } from '@backstage/core-app-api'; -import { renderWithEffects, TestApiRegistry } from '@backstage/test-utils'; +import { + MockErrorApi, + renderWithEffects, + TestApiRegistry, +} from '@backstage/test-utils'; import { CatalogKindHeader } from './CatalogKindHeader'; +import { errorApiRef } from '@backstage/core-plugin-api'; const entities: Entity[] = [ { @@ -57,21 +62,24 @@ const entities: Entity[] = [ }, }, ]; - -const apis = TestApiRegistry.from([ - catalogApiRef, - { - getEntityFacets: jest.fn().mockResolvedValue({ - facets: { - kind: [ - { value: 'Component', count: 2 }, - { value: 'Template', count: 1 }, - { value: 'System', count: 1 }, - ], - }, - } as GetEntityFacetsResponse), - }, -]); +const errorApi = new MockErrorApi(); +const apis = TestApiRegistry.from( + [ + catalogApiRef, + { + getEntityFacets: jest.fn().mockResolvedValue({ + facets: { + kind: [ + { value: 'Component', count: 2 }, + { value: 'Template', count: 1 }, + { value: 'System', count: 1 }, + ], + }, + } as GetEntityFacetsResponse), + }, + ], + [errorApiRef, errorApi], +); describe('', () => { it('renders available kinds', async () => { diff --git a/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.tsx b/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.tsx index 6689f3371d..3f5588853c 100644 --- a/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.tsx +++ b/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.tsx @@ -25,10 +25,12 @@ import { Theme, } from '@material-ui/core'; import { + catalogApiRef, EntityKindFilter, - useEntityKinds, useEntityListProvider, } from '@backstage/plugin-catalog-react'; +import useAsync from 'react-use/lib/useAsync'; +import { useApi } from '@backstage/core-plugin-api'; const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -51,7 +53,12 @@ export interface CatalogKindHeaderProps { export function CatalogKindHeader(props: CatalogKindHeaderProps) { const { initialFilter = 'component' } = props; const classes = useStyles(); - const { kinds: allKinds = [] } = useEntityKinds(); + const catalogApi = useApi(catalogApiRef); + const { value: allKinds } = useAsync(async () => { + return await catalogApi + .getEntityFacets({ facets: ['kind'] }) + .then(response => response.facets.kind?.map(f => f.value).sort() || []); + }); const { updateFilters, queryParameters } = useEntityListProvider(); const [selectedKind, setSelectedKind] = useState( @@ -72,7 +79,7 @@ export function CatalogKindHeader(props: CatalogKindHeaderProps) { // including selectedKind if it's unknown - but allows the selectedKind to get clobbered by the // more proper catalog kind if it exists. const options = [capitalize(selectedKind)] - .concat(allKinds) + .concat(allKinds ?? []) .sort() .reduce((acc, kind) => { acc[kind.toLocaleLowerCase('en-US')] = kind;