diff --git a/docs/features/software-catalog/catalog-customization.md b/docs/features/software-catalog/catalog-customization.md
index 07258a55cb..8f855776a0 100644
--- a/docs/features/software-catalog/catalog-customization.md
+++ b/docs/features/software-catalog/catalog-customization.md
@@ -34,15 +34,14 @@ export const CustomCatalogPage = ({
}: CatalogPageProps) => {
return (
-
-
-
- All your software catalog entities
-
-
+
+
+ }>
+
+ All your software catalog entities
+
-
@@ -51,8 +50,8 @@ export const CustomCatalogPage = ({
-
-
+
+
);
};
diff --git a/packages/core-components/src/layout/ContentHeader/ContentHeader.test.tsx b/packages/core-components/src/layout/ContentHeader/ContentHeader.test.tsx
index 498b859db1..37059766a8 100644
--- a/packages/core-components/src/layout/ContentHeader/ContentHeader.test.tsx
+++ b/packages/core-components/src/layout/ContentHeader/ContentHeader.test.tsx
@@ -32,7 +32,7 @@ describe('', () => {
it('should render with titleComponent', async () => {
const title = 'Custom title';
- const titleComponent = () =>
{title}
;
+ const titleComponent = {title}
;
const rendered = await renderInTestApp(
,
);
diff --git a/packages/core-components/src/layout/ContentHeader/ContentHeader.tsx b/packages/core-components/src/layout/ContentHeader/ContentHeader.tsx
index 4bda2d76af..fa797212e4 100644
--- a/packages/core-components/src/layout/ContentHeader/ContentHeader.tsx
+++ b/packages/core-components/src/layout/ContentHeader/ContentHeader.tsx
@@ -77,7 +77,7 @@ const ContentHeaderTitle = ({
type ContentHeaderProps = {
title?: ContentHeaderTitleProps['title'];
- titleComponent?: ComponentType;
+ titleComponent?: JSX.Element;
description?: string;
textAlign?: 'left' | 'right' | 'center';
};
@@ -92,7 +92,7 @@ export const ContentHeader = ({
const classes = useStyles({ textAlign })();
const renderedTitle = TitleComponent ? (
-
+ TitleComponent
) : (
);
diff --git a/plugins/catalog-react/src/components/EntityTypePicker/EntityTypePicker.test.tsx b/plugins/catalog-react/src/components/EntityTypePicker/EntityTypePicker.test.tsx
index 903a7ba4eb..a9ecf03e5c 100644
--- a/plugins/catalog-react/src/components/EntityTypePicker/EntityTypePicker.test.tsx
+++ b/plugins/catalog-react/src/components/EntityTypePicker/EntityTypePicker.test.tsx
@@ -15,7 +15,7 @@
*/
import React from 'react';
-import { fireEvent, render, waitFor } from '@testing-library/react';
+import { fireEvent, waitFor } from '@testing-library/react';
import { capitalize } from 'lodash';
import { CatalogApi } from '@backstage/catalog-client';
import { Entity } from '@backstage/catalog-model';
@@ -26,6 +26,7 @@ import { EntityKindFilter, EntityTypeFilter } from '../../filters';
import { AlertApi, alertApiRef } from '@backstage/core-plugin-api';
import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { renderWithEffects } from '@backstage/test-utils';
const entities: Entity[] = [
{
@@ -79,7 +80,7 @@ const apis = ApiRegistry.from([
describe('', () => {
it('renders available entity types', async () => {
- const rendered = render(
+ const rendered = await renderWithEffects(
', () => {
it('sets the selected type filter', async () => {
const updateFilters = jest.fn();
- const rendered = render(
+ const rendered = await renderWithEffects(
{
}
}, [error, alertApi]);
- if (!availableTypes || error) return null;
+ if (availableTypes.length === 0 || error) return null;
const items = [
{ value: 'all', label: 'All' },
diff --git a/plugins/catalog-react/src/hooks/index.ts b/plugins/catalog-react/src/hooks/index.ts
index 868e50c852..2f3ce8411d 100644
--- a/plugins/catalog-react/src/hooks/index.ts
+++ b/plugins/catalog-react/src/hooks/index.ts
@@ -22,6 +22,7 @@ export {
} from './useEntityListProvider';
export type { DefaultEntityFilters } from './useEntityListProvider';
export { useEntityTypeFilter } from './useEntityTypeFilter';
+export { useEntityKinds } from './useEntityKinds';
export { useOwnUser } from './useOwnUser';
export { useRelatedEntities } from './useRelatedEntities';
export { useStarredEntities } from './useStarredEntities';
diff --git a/plugins/catalog-react/src/hooks/useEntityKinds.ts b/plugins/catalog-react/src/hooks/useEntityKinds.ts
new file mode 100644
index 0000000000..1aaf40981a
--- /dev/null
+++ b/plugins/catalog-react/src/hooks/useEntityKinds.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2021 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.
+ */
+
+import { useEffect, useState } from 'react';
+import { useApi } from '@backstage/core-plugin-api';
+import { catalogApiRef } from '../api';
+
+export function useEntityKinds() {
+ const [kinds, setKinds] = useState(['component']);
+ const catalogApi = useApi(catalogApiRef);
+
+ useEffect(() => {
+ async function loadKinds() {
+ const entities = await catalogApi
+ .getEntities({ fields: ['kind'] })
+ .then(response => response.items);
+ setKinds([...new Set(entities.map(e => e.kind))].sort());
+ }
+ loadKinds();
+ }, [catalogApi]);
+
+ return kinds;
+}
diff --git a/plugins/catalog/src/components/CatalogPage/CatalogKindHeader.tsx b/plugins/catalog/src/components/CatalogPage/CatalogKindHeader.tsx
new file mode 100644
index 0000000000..985f8fed6a
--- /dev/null
+++ b/plugins/catalog/src/components/CatalogPage/CatalogKindHeader.tsx
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2021 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.
+ */
+
+import React, { useEffect, useState } from 'react';
+import {
+ capitalize,
+ createStyles,
+ InputBase,
+ makeStyles,
+ MenuItem,
+ Select,
+ Theme,
+} from '@material-ui/core';
+import {
+ EntityKindFilter,
+ useEntityKinds,
+ useEntityListProvider,
+} from '@backstage/plugin-catalog-react';
+
+const useStyles = makeStyles((theme: Theme) =>
+ createStyles({
+ root: {
+ ...theme.typography.h4,
+ },
+ }),
+);
+
+type CatalogKindHeaderProps = {
+ initialFilter?: string;
+};
+
+export const CatalogKindHeader = ({
+ initialFilter = 'Component',
+}: CatalogKindHeaderProps) => {
+ const classes = useStyles();
+ const allKinds = useEntityKinds();
+ const { updateFilters, queryParameters } = useEntityListProvider();
+
+ const [selectedKind, setSelectedKind] = useState(
+ [queryParameters.kind].flat()[0] ?? initialFilter,
+ );
+
+ useEffect(() => {
+ updateFilters({
+ kind: selectedKind ? new EntityKindFilter(selectedKind) : undefined,
+ });
+ }, [selectedKind, updateFilters]);
+
+ return (
+ }
+ value={selectedKind}
+ onChange={e => setSelectedKind(e.target.value as string)}
+ classes={classes}
+ >
+ {allKinds.map(kind => (
+
+ ))}
+
+ );
+};
diff --git a/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx b/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx
index a4f6c01bc8..913b3dfeb6 100644
--- a/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx
+++ b/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx
@@ -43,6 +43,7 @@ import {
EntityListContainer,
FilterContainer,
} from '../FilteredEntityLayout';
+import { CatalogKindHeader } from './CatalogKindHeader';
export type CatalogPageProps = {
initiallySelectedFilter?: UserListFilterKind;
@@ -61,18 +62,17 @@ export const CatalogPage = ({
return (
-
-
-
- All your software catalog entities
-
-
+
+
+ }>
+
+ All your software catalog entities
+
-
@@ -83,8 +83,8 @@ export const CatalogPage = ({
-
-
+
+
);
};