diff --git a/.changeset/pretty-seas-hug.md b/.changeset/pretty-seas-hug.md new file mode 100644 index 0000000000..216f9af18f --- /dev/null +++ b/.changeset/pretty-seas-hug.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Fixed an issue causing entities of kind user and group to be empty when an owner was selected diff --git a/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx b/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx index 45ed6079cc..de85fa1042 100644 --- a/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx +++ b/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx @@ -32,6 +32,7 @@ import { catalogApiRef } from '../api'; import { MockStarredEntitiesApi, starredEntitiesApiRef } from '../apis'; import { EntityKindFilter, + EntityOwnerFilter, EntityTextFilter, EntityTypeFilter, EntityUserFilter, @@ -298,6 +299,48 @@ describe('', () => { expect(result.current.pageInfo).toBeUndefined(); }); + + it('should omit owners filter when kind is "user"', async () => { + const { result } = renderHook(() => useEntityList(), { + wrapper: createWrapper({ pagination }), + }); + + act(() => { + result.current.updateFilters({ + kind: new EntityKindFilter('user', 'User'), + owners: new EntityOwnerFilter(['user:default/guest']), + }); + }); + + await waitFor(() => { + expect(mockCatalogApi.getEntities).toHaveBeenCalled(); + }); + + expect(mockCatalogApi.getEntities).toHaveBeenCalledWith({ + filter: { kind: 'user' }, + }); + }); + + it('should omit owners filter when kind is "group"', async () => { + const { result } = renderHook(() => useEntityList(), { + wrapper: createWrapper({ pagination }), + }); + + act(() => { + result.current.updateFilters({ + kind: new EntityKindFilter('group', 'Group'), + owners: new EntityOwnerFilter(['group:default/team-a']), + }); + }); + + await waitFor(() => { + expect(mockCatalogApi.getEntities).toHaveBeenCalled(); + }); + + expect(mockCatalogApi.getEntities).toHaveBeenCalledWith({ + filter: { kind: 'group' }, + }); + }); }); describe('', () => { @@ -552,6 +595,52 @@ describe('', () => { }); }); }); + + it('should omit owners filter when kind is "user"', async () => { + const { result } = renderHook(() => useEntityList(), { + wrapper: createWrapper({ pagination }), + }); + + act(() => { + result.current.updateFilters({ + kind: new EntityKindFilter('user', 'User'), + owners: new EntityOwnerFilter(['user:default/guest']), + }); + }); + + await waitFor(() => { + expect(mockCatalogApi.queryEntities).toHaveBeenCalled(); + }); + + expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith( + expect.objectContaining({ + filter: { kind: 'user' }, + }), + ); + }); + + it('should omit owners filter when kind is "group"', async () => { + const { result } = renderHook(() => useEntityList(), { + wrapper: createWrapper({ pagination }), + }); + + act(() => { + result.current.updateFilters({ + kind: new EntityKindFilter('group', 'Group'), + owners: new EntityOwnerFilter(['group:default/team-a']), + }); + }); + + await waitFor(() => { + expect(mockCatalogApi.queryEntities).toHaveBeenCalled(); + }); + + expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith( + expect.objectContaining({ + filter: { kind: 'group' }, + }), + ); + }); }); }); @@ -801,4 +890,50 @@ describe(``, () => { expect(result.current.error).toBeDefined(); }); }); + + it('should omit owners filter when kind is "user"', async () => { + const { result } = renderHook(() => useEntityList(), { + wrapper: createWrapper({ pagination }), + }); + + act(() => { + result.current.updateFilters({ + kind: new EntityKindFilter('user', 'User'), + owners: new EntityOwnerFilter(['user:default/guest']), + }); + }); + + await waitFor(() => { + expect(mockCatalogApi.queryEntities).toHaveBeenCalled(); + }); + + expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith( + expect.objectContaining({ + filter: { kind: 'user' }, + }), + ); + }); + + it('should omit owners filter when kind is "group"', async () => { + const { result } = renderHook(() => useEntityList(), { + wrapper: createWrapper({ pagination }), + }); + + act(() => { + result.current.updateFilters({ + kind: new EntityKindFilter('group', 'Group'), + owners: new EntityOwnerFilter(['group:default/team-a']), + }); + }); + + await waitFor(() => { + expect(mockCatalogApi.queryEntities).toHaveBeenCalled(); + }); + + expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith( + expect.objectContaining({ + filter: { kind: 'group' }, + }), + ); + }); }); diff --git a/plugins/catalog-react/src/hooks/useEntityListProvider.tsx b/plugins/catalog-react/src/hooks/useEntityListProvider.tsx index 1d3afd8d9b..560e2ba987 100644 --- a/plugins/catalog-react/src/hooks/useEntityListProvider.tsx +++ b/plugins/catalog-react/src/hooks/useEntityListProvider.tsx @@ -241,7 +241,13 @@ export const EntityListProvider = ( // based on the requested filters changing. const [{ loading, error }, refresh] = useAsyncFn( async () => { - const compacted = compact(Object.values(requestedFilters)); + const kindValue = + requestedFilters.kind?.value?.toLocaleLowerCase('en-US'); + const adjustedFilters = + kindValue === 'user' || kindValue === 'group' + ? { ...requestedFilters, owners: undefined } + : requestedFilters; + const compacted = compact(Object.values(adjustedFilters)); const queryParams = Object.keys(requestedFilters).reduce( (params, key) => {