catalog-react: fix filter resetting bug in UserListPicker
Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
---
|
||||
|
||||
Fix bug with filter resetting based on user ownership
|
||||
@@ -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';
|
||||
@@ -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,
|
||||
),
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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':
|
||||
|
||||
Reference in New Issue
Block a user