From 9a06d183851b450f8874728da903eb29124152e2 Mon Sep 17 00:00:00 2001 From: Tim Hansen Date: Thu, 3 Mar 2022 10:54:07 -0700 Subject: [PATCH 1/2] Add allowedKinds option to CatalogKindHeader Signed-off-by: Tim Hansen --- .changeset/gorgeous-trains-clap.md | 5 +++ plugins/catalog/api-report.md | 2 +- .../CatalogKindHeader.test.tsx | 43 +++++++++++++++++++ .../CatalogKindHeader/CatalogKindHeader.tsx | 31 +++++++++---- 4 files changed, 72 insertions(+), 9 deletions(-) create mode 100644 .changeset/gorgeous-trains-clap.md diff --git a/.changeset/gorgeous-trains-clap.md b/.changeset/gorgeous-trains-clap.md new file mode 100644 index 0000000000..d0abf6148a --- /dev/null +++ b/.changeset/gorgeous-trains-clap.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog': patch +--- + +Added an `allowedKinds` option to `CatalogKindHeader` to limit entity kinds available in the dropdown. diff --git a/plugins/catalog/api-report.md b/plugins/catalog/api-report.md index 3223d6aa59..43cde23c57 100644 --- a/plugins/catalog/api-report.md +++ b/plugins/catalog/api-report.md @@ -74,7 +74,7 @@ export function CatalogKindHeader(props: CatalogKindHeaderProps): JSX.Element; // @public export interface CatalogKindHeaderProps { - // (undocumented) + allowedKinds?: string[]; initialFilter?: string; } diff --git a/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.test.tsx b/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.test.tsx index a7dc18eae2..15d41f3ab3 100644 --- a/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.test.tsx +++ b/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.test.tsx @@ -169,4 +169,47 @@ describe('', () => { kind: new EntityKindFilter('template'), }); }); + + it('limits kinds when allowedKinds is set', async () => { + const rendered = await renderWithEffects( + + + + + , + ); + + const input = rendered.getByText('Components'); + fireEvent.mouseDown(input); + + expect( + rendered.getByRole('option', { name: 'Components' }), + ).toBeInTheDocument(); + expect( + rendered.getByRole('option', { name: 'Systems' }), + ).toBeInTheDocument(); + expect( + rendered.queryByRole('option', { name: 'Templates' }), + ).not.toBeInTheDocument(); + }); + + it('renders kind from the query parameter even when not in allowedKinds', async () => { + const rendered = await renderWithEffects( + + + + + , + ); + + expect(rendered.getByText('Frobs')).toBeInTheDocument(); + const input = rendered.getByText('Frobs'); + fireEvent.mouseDown(input); + + expect( + rendered.getByRole('option', { name: 'Systems' }), + ).toBeInTheDocument(); + }); }); diff --git a/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.tsx b/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.tsx index 27184bafef..5b87919f45 100644 --- a/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.tsx +++ b/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.tsx @@ -46,12 +46,21 @@ const useStyles = makeStyles((theme: Theme) => * @public */ export interface CatalogKindHeaderProps { + /** + * Entity kinds to show in the dropdown; by default all kinds are fetched from the catalog and + * displayed. + */ + allowedKinds?: string[]; + /** + * The initial kind to select; defaults to 'component'. A kind filter entered directly in the + * query parameter will override this value. + */ initialFilter?: string; } /** @public */ export function CatalogKindHeader(props: CatalogKindHeaderProps) { - const { initialFilter = 'component' } = props; + const { initialFilter = 'component', allowedKinds } = props; const classes = useStyles(); const catalogApi = useApi(catalogApiRef); const { value: allKinds } = useAsync(async () => { @@ -91,13 +100,19 @@ export function CatalogKindHeader(props: CatalogKindHeaderProps) { // enforced casing from the catalog-backend. This makes a key/value record for the Select options, // 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 ?? []) - .sort() - .reduce((acc, kind) => { - acc[kind.toLocaleLowerCase('en-US')] = kind; - return acc; - }, {} as Record); + const availableKinds = [capitalize(selectedKind)].concat( + allKinds?.filter(k => + allowedKinds + ? allowedKinds.some( + a => a.toLocaleLowerCase('en-US') === k.toLocaleLowerCase('en-US'), + ) + : true, + ) ?? [], + ); + const options = availableKinds.sort().reduce((acc, kind) => { + acc[kind.toLocaleLowerCase('en-US')] = kind; + return acc; + }, {} as Record); return (