diff --git a/.changeset/twenty-queens-grow.md b/.changeset/twenty-queens-grow.md
new file mode 100644
index 0000000000..1236488dbe
--- /dev/null
+++ b/.changeset/twenty-queens-grow.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-scaffolder': minor
+---
+
+Added EntityOwnerPicker component to the TemplateListPage to allow filtering on owner
diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.test.ts b/plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.test.ts
index 742efaab9f..1d9eaa8af7 100644
--- a/plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.test.ts
+++ b/plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.test.ts
@@ -70,6 +70,21 @@ describe('useFacetsEntities', () => {
expect(result.current[0]).toEqual({ value: { items: [] }, loading: true });
});
+ it(`should return empty response when facet is not present`, async () => {
+ mockedGetEntityFacets.mockResolvedValueOnce({
+ facets: { 'metadata.tags': [{ value: 'tag', count: 1 }] },
+ });
+ mockedGetEntitiesByRefs.mockResolvedValueOnce({ items: [] });
+ const { result } = renderHook(() => useFacetsEntities({ enabled: true }));
+ result.current[1]({ text: '' });
+ await waitFor(() => {
+ expect(result.current[0]).toEqual({
+ value: { items: [] },
+ loading: false,
+ });
+ });
+ });
+
it(`should return the owners`, async () => {
const entityRefs = ['component:default/e1', 'component:default/e2'];
mockedGetEntityFacets.mockResolvedValue(facetsFromEntityRefs(entityRefs));
diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.ts b/plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.ts
index 10a5c5a8c2..9bb27eab98 100644
--- a/plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.ts
+++ b/plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.ts
@@ -52,7 +52,7 @@ export function useFacetsEntities({ enabled }: { enabled: boolean }) {
const facetsResponse = await catalogApi.getEntityFacets({
facets: [facet],
});
- const entityRefs = facetsResponse.facets[facet].map(e => e.value);
+ const entityRefs = facetsResponse.facets[facet]?.map(e => e.value) ?? [];
return catalogApi
.getEntitiesByRefs({ entityRefs })
diff --git a/plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.test.tsx b/plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.test.tsx
index ee36d876cf..2ad0752cc8 100644
--- a/plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.test.tsx
+++ b/plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.test.tsx
@@ -45,6 +45,9 @@ describe('TemplateListPage', () => {
getEntityFacets: async () => ({
facets: { 'spec.type': [{ value: 'service', count: 1 }] },
}),
+ getEntitiesByRefs: async () => ({
+ items: [],
+ }),
};
it('should render the search bar for templates', async () => {
@@ -114,6 +117,28 @@ describe('TemplateListPage', () => {
expect(getByText('Categories')).toBeInTheDocument();
});
+ it('should render the EntityOwnerPicker', async () => {
+ const { getByText } = await renderInTestApp(
+
+
+ ,
+ { mountedRoutes: { '/': rootRouteRef } },
+ );
+
+ expect(getByText('Owner')).toBeInTheDocument();
+ });
+
// eslint-disable-next-line jest/no-disabled-tests
it.skip('should render the EntityTag picker', async () => {
const { getByText } = await renderInTestApp(
diff --git a/plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.tsx b/plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.tsx
index 400bc9d192..4042506d1e 100644
--- a/plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.tsx
+++ b/plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.tsx
@@ -34,6 +34,7 @@ import {
EntityTagPicker,
CatalogFilterLayout,
UserListPicker,
+ EntityOwnerPicker,
} from '@backstage/plugin-catalog-react';
import {
ScaffolderPageContextMenu,
@@ -198,6 +199,7 @@ export const TemplateListPage = (props: TemplateListPageProps) => {
/>
+