diff --git a/.changeset/pink-countries-pump.md b/.changeset/pink-countries-pump.md
index 01c75b01e7..b7a79238fd 100644
--- a/.changeset/pink-countries-pump.md
+++ b/.changeset/pink-countries-pump.md
@@ -3,14 +3,22 @@
'@backstage/plugin-catalog-react': minor
---
-Reworks how catalog entities are fetched from the `catalog-backend` for the main
-catalog homepage. This enables easier customization of the catalog, and supports
-showing all types of catalog entities rather than just components.
+The default `CatalogPage` has been reworked to be more composable and make
+customization easier. This change only affects those who have replaced the
+default `CatalogPage` with a custom implementation; others can safely ignore the
+rest of this changelog.
-This change only affects those that have replaced the default `CatalogPage` with
-a custom implementation.
+If you created a custom `CatalogPage` to **add or remove tabs** from the
+catalog, a custom page is no longer necessary. The fixed tabs have been replaced
+with a `spec.type` dropdown that shows all available `Component` types in the
+catalog.
-The `useFilteredEntities` and `useEntityFilterGroups` hooks have been replaced
-with a `useEntityListProvider` hook and wrapping `EntityListProvider` context.
-This handles querying the `catalog-backend` and applying filters that can either
-provide query parameters or a frontend filtering function.
+For other needs, customizing the `CatalogPage` should now be easier. The new
+[CatalogPage.tsx](https://github.com/backstage/backstage/blob/9a4baa74509b6452d7dc054d34cf079f9997166d/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx)
+shows the default implementation. Overriding this with your own, similar
+`CatalogPage` component in your `App.tsx` routing allows you to adjust the
+layout, header, and which filters are available.
+
+See the documentation added on [Catalog
+Customization](https://backstage.io/docs/features/software-catalog/catalog-customization)
+for instructions.
diff --git a/docs/features/software-catalog/catalog-customization.md b/docs/features/software-catalog/catalog-customization.md
new file mode 100644
index 0000000000..bdad78a35c
--- /dev/null
+++ b/docs/features/software-catalog/catalog-customization.md
@@ -0,0 +1,141 @@
+---
+id: catalog-customization
+title: Catalog Customization
+# prettier-ignore
+description: How to add custom filters or interface elements to the Backstage software catalog
+---
+
+The Backstage software catalog comes with a default `CatalogIndexPage` to filter
+and find catalog entities. This is already set up by default by
+`@backstage/create-app`.
+
+If you want to change the default index page - such as to add a custom filter to
+the catalog - you can replace the routing in `App.tsx` to point to your own
+`CatalogIndexPage`.
+
+For example, suppose that I want to allow filtering by a custom annotation added
+to entities, `company.com/itgc-enabled`. To start, I'll copy the code for the
+default catalog page, either in a new plugin or just in the `app` package:
+
+```tsx
+// imports, etc omitted for brevity. for full source see:
+// https://github.com/backstage/backstage/blob/master/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx
+export const CustomCatalogIndexPage = () => {
+ return (
+
+
+
+
+ All your software catalog entities
+
+
+
+
+ );
+};
+```
+
+The `EntityListProvider` shown here provides a list of entities from the
+`catalog-backend`, and a way to hook in filters. `EntityListProvider` has a
+[generic](https://www.typescriptlang.org/docs/handbook/2/generics.html) argument
+that can be extended to provide your own filters.
+
+Now we're ready to create a new filter that implements the `EntityFilter`
+interface:
+
+```ts
+import { EntityFilter } from '@backstage/catalog-react';
+import { Entity } from '@backstage/catalog-model';
+
+class ItgcEntityFilter implements EntityFilter {
+ filterEntity(entity: Entity): boolean {
+ return entity.metadata.annotations?.['company.com/itgc-enabled'] === true;
+ }
+}
+```
+
+The `EntityFilter` interface permits backend filters, which are passed along to
+the `catalog-backend` - or frontend filters, which are applied after entities
+are loaded from the backend.
+
+Let's create the custom filter shape extending the default and update the
+`EntityListProvider` in the custom index page to use it:
+
+```diff
++export type CustomFilters = DefaultEntityFilters & {
++ itgc: ItgcEntityFilter;
++};
+
+export const CustomCatalogIndexPage = () => {
+...
+
+-
++ >
+
+...
+```
+
+To control this filter, we can create a React component that shows a checkbox.
+This component will make use of the `useEntityListProvider` hook, which also
+accepts the same generic so we can use the added filter field:
+
+```tsx
+export const ItgcPicker = () => {
+ const {
+ filters: { itgc: currentItgcFilter },
+ updateFilters,
+ } = useEntityListProvider
();
+ const [enabled, setEnabled] = useState(false);
+
+ useEffect(() => {
+ updateFilters({ itgc: enabled ? new ItgcEntityFilter() : undefined });
+ }, [enabled, updateFilters]);
+
+ return (
+ setEnabled(isEnabled => !isEnabled)}
+ name="itgc-picker"
+ />
+ }
+ label="ITGC Required"
+ />
+ );
+};
+```
+
+Now I can add the component to `CustomCatalogIndexPage`:
+
+```diff
+export const CustomCatalogIndexPage = () => {
+ return (
+ ...
+
+
+
+
+
++
+
+
+
+
+ ...
+};
+```
+
+The same method can be used to customize the _default_ filters with a different
+interface - for such usage, the generic argument won't be needed since the
+filter shape remains the same as the default.
diff --git a/microsite/sidebars.json b/microsite/sidebars.json
index 6c42614a61..b8ed72596d 100644
--- a/microsite/sidebars.json
+++ b/microsite/sidebars.json
@@ -43,6 +43,7 @@
"features/software-catalog/well-known-statuses",
"features/software-catalog/extending-the-model",
"features/software-catalog/external-integrations",
+ "features/software-catalog/catalog-customization",
"features/software-catalog/software-catalog-api"
]
},
diff --git a/mkdocs.yml b/mkdocs.yml
index 574b04f8f7..a87acc91c8 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -40,6 +40,7 @@ nav:
- Well-known Statuses: 'features/software-catalog/well-known-statuses.md'
- Extending the model: 'features/software-catalog/extending-the-model.md'
- External integrations: 'features/software-catalog/external-integrations.md'
+ - Catalog Customization: 'features/software-catalog/catalog-customization.md'
- API: 'features/software-catalog/api.md'
- Kubernetes:
- Overview: 'features/kubernetes/index.md'
diff --git a/plugins/catalog-react/src/components/EntityKindPicker/EntityKindPicker.tsx b/plugins/catalog-react/src/components/EntityKindPicker/EntityKindPicker.tsx
index e8c783de39..86980d098f 100644
--- a/plugins/catalog-react/src/components/EntityKindPicker/EntityKindPicker.tsx
+++ b/plugins/catalog-react/src/components/EntityKindPicker/EntityKindPicker.tsx
@@ -39,5 +39,8 @@ export const EntityKindPicker = ({
if (hidden) return null;
+ // TODO(timbonicus): This should load available kinds from the catalog-backend, similar to
+ // EntityTypePicker.
+
return Kind filter not yet available;
};