Merge pull request #9961 from backstage/timbonicus/catalog-allowed-kinds

Add allowedKinds option to CatalogKindHeader
This commit is contained in:
Tim Hansen
2022-03-09 11:22:21 -07:00
committed by GitHub
4 changed files with 73 additions and 10 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog': patch
---
Added an `allowedKinds` option to `CatalogKindHeader` to limit entity kinds available in the dropdown.
+1 -1
View File
@@ -74,7 +74,7 @@ export function CatalogKindHeader(props: CatalogKindHeaderProps): JSX.Element;
// @public
export interface CatalogKindHeaderProps {
// (undocumented)
allowedKinds?: string[];
initialFilter?: string;
}
@@ -169,4 +169,47 @@ describe('<CatalogKindHeader />', () => {
kind: new EntityKindFilter('template'),
});
});
it('limits kinds when allowedKinds is set', async () => {
const rendered = await renderWithEffects(
<ApiProvider apis={apis}>
<MockEntityListContextProvider>
<CatalogKindHeader allowedKinds={['component', 'system']} />
</MockEntityListContextProvider>
</ApiProvider>,
);
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(
<ApiProvider apis={apis}>
<MockEntityListContextProvider
value={{ queryParameters: { kind: 'Frob' } }}
>
<CatalogKindHeader allowedKinds={['system']} />
</MockEntityListContextProvider>
</ApiProvider>,
);
expect(rendered.getByText('Frobs')).toBeInTheDocument();
const input = rendered.getByText('Frobs');
fireEvent.mouseDown(input);
expect(
rendered.getByRole('option', { name: 'Systems' }),
).toBeInTheDocument();
});
});
@@ -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 () => {
@@ -65,7 +74,7 @@ export function CatalogKindHeader(props: CatalogKindHeaderProps) {
} = useEntityList();
const queryParamKind = useMemo(
() => [kindParameter].flat()[0],
() => [kindParameter].flat()[0]?.toLocaleLowerCase('en-US'),
[kindParameter],
);
const [selectedKind, setSelectedKind] = useState(
@@ -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<string, string>);
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<string, string>);
return (
<Select