bugfix: [3310] Favoriting a component resets interface to your owned components
update changeset remove unused import fix changeset message fix vale errors?
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog': patch
|
||||
---
|
||||
|
||||
bug fix: 3310 fixes reloading entities with the default owned filter
|
||||
@@ -80,6 +80,14 @@ type Props = {
|
||||
onChange?: OnChangeCallback;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sidebar filter type and human readable label for it. owned/starred/all
|
||||
*/
|
||||
export type CatalogFilterType = {
|
||||
id: string;
|
||||
label: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* The main filter group in the sidebar, toggling owned/starred/all.
|
||||
*/
|
||||
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
} from '@backstage/core';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { MockStorageApi, wrapInTestApp } from '@backstage/test-utils';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import { fireEvent, render, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { EntityFilterGroupsProvider } from '../../filter';
|
||||
import { CatalogPage } from './CatalogPage';
|
||||
@@ -128,4 +128,24 @@ describe('CatalogPage', () => {
|
||||
fireEvent.click(getByText(/All/));
|
||||
expect(await findByText(/All \(2\)/)).toBeInTheDocument();
|
||||
});
|
||||
// this test is for fixing the bug after favoriting an entity, the matching entities defaulting
|
||||
// to "owned" filter and not based on the selected filter
|
||||
it('should render the correct entities filtered on the selectedfilter', async () => {
|
||||
const { findByText, findAllByTitle, getByText } = renderWrapped(
|
||||
<CatalogPage />,
|
||||
);
|
||||
expect(await findByText(/Owned \(1\)/)).toBeInTheDocument();
|
||||
expect(await findByText(/Starred/)).toBeInTheDocument();
|
||||
fireEvent.click(getByText(/Starred/));
|
||||
expect(await findByText(/Starred \(0\)/)).toBeInTheDocument();
|
||||
fireEvent.click(getByText(/All/));
|
||||
expect(await findByText(/All \(2\)/)).toBeInTheDocument();
|
||||
|
||||
const starredIcons = await findAllByTitle('Add to favorites');
|
||||
fireEvent.click(starredIcons[0]);
|
||||
expect(await findByText(/All \(2\)/)).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(getByText(/Starred/));
|
||||
waitFor(() => expect(findByText(/Starred \(1\)/)).toBeInTheDocument());
|
||||
});
|
||||
});
|
||||
|
||||
@@ -31,7 +31,11 @@ import React, { useCallback, useMemo, useState } from 'react';
|
||||
import { Link as RouterLink } from 'react-router-dom';
|
||||
import { EntityFilterGroupsProvider, useFilteredEntities } from '../../filter';
|
||||
import { useStarredEntities } from '../../hooks/useStarredEntities';
|
||||
import { ButtonGroup, CatalogFilter } from '../CatalogFilter/CatalogFilter';
|
||||
import {
|
||||
ButtonGroup,
|
||||
CatalogFilter,
|
||||
CatalogFilterType,
|
||||
} from '../CatalogFilter/CatalogFilter';
|
||||
import { CatalogTable } from '../CatalogTable/CatalogTable';
|
||||
import { ResultsFilter } from '../ResultsFilter/ResultsFilter';
|
||||
import { useOwnUser } from '../useOwnUser';
|
||||
@@ -65,7 +69,9 @@ const CatalogPageContents = () => {
|
||||
const errorApi = useApi(errorApiRef);
|
||||
const { isStarredEntity } = useStarredEntities();
|
||||
const [selectedTab, setSelectedTab] = useState<string>();
|
||||
const [selectedSidebarItem, setSelectedSidebarItem] = useState<string>();
|
||||
const [selectedSidebarItem, setSelectedSidebarItem] = useState<
|
||||
CatalogFilterType
|
||||
>();
|
||||
const orgName = configApi.getOptionalString('organization.name') ?? 'Company';
|
||||
|
||||
const addMockData = useCallback(async () => {
|
||||
@@ -180,13 +186,15 @@ const CatalogPageContents = () => {
|
||||
<div>
|
||||
<CatalogFilter
|
||||
buttonGroups={filterGroups}
|
||||
onChange={({ label }) => setSelectedSidebarItem(label)}
|
||||
initiallySelected="owned"
|
||||
onChange={({ label, id }) =>
|
||||
setSelectedSidebarItem({ label, id })
|
||||
}
|
||||
initiallySelected={selectedSidebarItem?.id ?? 'owned'}
|
||||
/>
|
||||
<ResultsFilter availableTags={availableTags} />
|
||||
</div>
|
||||
<CatalogTable
|
||||
titlePreamble={selectedSidebarItem ?? ''}
|
||||
titlePreamble={selectedSidebarItem?.label ?? ''}
|
||||
entities={matchingEntities}
|
||||
loading={loading}
|
||||
error={error}
|
||||
|
||||
@@ -43,15 +43,19 @@ export const useEntityFilterGroup = (
|
||||
filterGroupStates,
|
||||
} = context;
|
||||
|
||||
// Intentionally consider initial set only at mount time
|
||||
// on state changes unregisters and registers the filtergroup
|
||||
// ensure that it re-registers with the correct filter as the prop changes and not the default
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
const initialMemo = useMemo(() => initialSelectedFilters?.slice(), []);
|
||||
const initialMemo = useMemo(() => {
|
||||
return initialSelectedFilters?.slice();
|
||||
}, [initialSelectedFilters]);
|
||||
|
||||
// Register the group on mount, and unregister on unmount
|
||||
useEffect(() => {
|
||||
register(filterGroupId, filterGroup, initialMemo);
|
||||
return () => unregister(filterGroupId);
|
||||
}, [register, unregister, filterGroupId, filterGroup, initialMemo]);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [register, unregister, filterGroupId, filterGroup]);
|
||||
|
||||
const setSelectedFilters = useCallback(
|
||||
(filters: string[]) => {
|
||||
|
||||
Reference in New Issue
Block a user