Skip to content

Commit

Permalink
catalog-react: fix filter resetting bug in UserListPicker
Browse files Browse the repository at this point in the history
Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com>
  • Loading branch information
mtlewis committed Feb 1, 2022
1 parent d3c107d commit 300f8cd
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .changeset/itchy-bulldogs-dance.md
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-react': patch
---

Fix bug with filter resetting based on user ownership
Expand Up @@ -69,8 +69,9 @@ const apis = TestApiRegistry.from(
[storageApiRef, MockStorageApi.create()],
);

const mockIsOwnedEntity = (entity: Entity) =>
entity.metadata.name === 'component-1';
const mockIsOwnedEntity = jest.fn(
(entity: Entity) => entity.metadata.name === 'component-1',
);

const mockIsStarredEntity = (entity: Entity) =>
entity.metadata.name === 'component-3';
Expand Down Expand Up @@ -250,4 +251,82 @@ describe('<UserListPicker />', () => {
),
});
});

describe('filter resetting', () => {
let updateFilters: jest.Mock;

const picker = ({ loading }: { loading: boolean }) => (
<ApiProvider apis={apis}>
<MockEntityListContextProvider
value={{ backendEntities, updateFilters, loading }}
>
<UserListPicker initialFilter="owned" />
</MockEntityListContextProvider>
</ApiProvider>
);

beforeEach(() => {
updateFilters = jest.fn();
});

describe('when the user does not own any entities', () => {
beforeEach(() => {
mockIsOwnedEntity.mockReturnValue(false);
});

it('does not reset the filter while entities are loading', () => {
render(picker({ loading: true }));

expect(updateFilters).not.toHaveBeenCalledWith({
user: new UserListFilter(
'all',
mockIsOwnedEntity,
mockIsStarredEntity,
),
});
});

it('resets the filter to "all" when entities are loaded', () => {
render(picker({ loading: false }));

expect(updateFilters).toHaveBeenLastCalledWith({
user: new UserListFilter(
'all',
mockIsOwnedEntity,
mockIsStarredEntity,
),
});
});
});

describe('when the user owns entities', () => {
beforeEach(() => {
mockIsOwnedEntity.mockReturnValue(true);
});

it('does not reset the filter while entities are loading', () => {
render(picker({ loading: true }));

expect(updateFilters).not.toHaveBeenCalledWith({
user: new UserListFilter(
'all',
mockIsOwnedEntity,
mockIsStarredEntity,
),
});
});

it('does not reset the filter when entities are loaded', () => {
render(picker({ loading: false }));

expect(updateFilters).toHaveBeenLastCalledWith({
user: new UserListFilter(
'owned',
mockIsOwnedEntity,
mockIsStarredEntity,
),
});
});
});
});
});
Expand Up @@ -130,7 +130,7 @@ export const UserListPicker = ({
const classes = useStyles();
const configApi = useApi(configApiRef);
const orgName = configApi.getOptionalString('organization.name') ?? 'Company';
const { filters, updateFilters, backendEntities, queryParameters } =
const { filters, updateFilters, backendEntities, queryParameters, loading } =
useEntityListProvider();

// Remove group items that aren't in availableFilters and exclude
Expand Down Expand Up @@ -161,19 +161,36 @@ export const UserListPicker = ({
[isOwnedEntity, isStarredEntity],
);

const [selectedUserFilter, setSelectedUserFilter] = useState(
[queryParameters.user].flat()[0] ?? initialFilter,
);

// To show proper counts for each section, apply all other frontend filters _except_ the user
// filter that's controlled by this picker.
const [entitiesWithoutUserFilter, setEntitiesWithoutUserFilter] =
useState(backendEntities);
const totalOwnedUserEntities = entitiesWithoutUserFilter.filter(entity =>
ownedFilter.filterEntity(entity),
).length;
const [selectedUserFilter, setSelectedUserFilter] = useState(
totalOwnedUserEntities > 0
? [queryParameters.user].flat()[0] ?? initialFilter
: 'all',
const entitiesWithoutUserFilter = useMemo(
() =>
backendEntities.filter(
reduceEntityFilters(
compact(Object.values({ ...filters, user: undefined })),
),
),
[filters, backendEntities],
);

const totalOwnedUserEntities = useMemo(
() =>
entitiesWithoutUserFilter.filter(entity =>
ownedFilter.filterEntity(entity),
).length,
[entitiesWithoutUserFilter, ownedFilter],
);

useEffect(() => {
if (!loading && totalOwnedUserEntities === 0) {
setSelectedUserFilter('all');
}
}, [loading, totalOwnedUserEntities, setSelectedUserFilter]);

useEffect(() => {
updateFilters({
user: selectedUserFilter
Expand All @@ -186,13 +203,6 @@ export const UserListPicker = ({
});
}, [selectedUserFilter, isOwnedEntity, isStarredEntity, updateFilters]);

useEffect(() => {
const filterFn = reduceEntityFilters(
compact(Object.values({ ...filters, user: undefined })),
);
setEntitiesWithoutUserFilter(backendEntities.filter(filterFn));
}, [filters, backendEntities]);

function getFilterCount(id: UserListFilterKind) {
switch (id) {
case 'owned':
Expand Down

0 comments on commit 300f8cd

Please sign in to comment.