Merge pull request #13580 from kuangp/feat/tagPicker/counts

feat(EntityTagPicker): support showing option counts
This commit is contained in:
Fredrik Adelöw
2022-09-08 11:31:42 +02:00
committed by GitHub
5 changed files with 56 additions and 8 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-react': patch
---
Support showing counts in option labels of the `EntityTagPicker`. You can enable this by adding the `showCounts` property
+8 -1
View File
@@ -364,7 +364,14 @@ export class EntityTagFilter implements EntityFilter {
}
// @public (undocumented)
export const EntityTagPicker: () => JSX.Element | null;
export const EntityTagPicker: (
props: EntityTagPickerProps,
) => JSX.Element | null;
// @public (undocumented)
export type EntityTagPickerProps = {
showCounts?: boolean;
};
// @public
export class EntityTextFilter implements EntityFilter {
@@ -28,7 +28,9 @@ const tags = ['tag1', 'tag2', 'tag3', 'tag4'];
describe('<EntityTagPicker/>', () => {
const mockCatalogApiRef = {
getEntityFacets: async () => ({
facets: { 'metadata.tags': tags.map(value => ({ value })) },
facets: {
'metadata.tags': tags.map((value, idx) => ({ value, count: idx })),
},
}),
} as unknown as CatalogApi;
@@ -68,6 +70,26 @@ describe('<EntityTagPicker/>', () => {
]);
});
it('renders tags with counts', async () => {
const rendered = render(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<MockEntityListContextProvider value={{}}>
<EntityTagPicker showCounts />
</MockEntityListContextProvider>
</TestApiProvider>,
);
await waitFor(() => expect(rendered.getByText('Tags')).toBeInTheDocument());
fireEvent.click(rendered.getByTestId('tag-picker-expand'));
expect(rendered.getAllByRole('option').map(o => o.textContent)).toEqual([
'tag1 (0)',
'tag2 (1)',
'tag3 (2)',
'tag4 (3)',
]);
});
it('respects the query parameter filter value', async () => {
const updateFilters = jest.fn();
const queryParameters = { tags: ['tag3'] };
@@ -49,7 +49,12 @@ const icon = <CheckBoxOutlineBlankIcon fontSize="small" />;
const checkedIcon = <CheckBoxIcon fontSize="small" />;
/** @public */
export const EntityTagPicker = () => {
export type EntityTagPickerProps = {
showCounts?: boolean;
};
/** @public */
export const EntityTagPicker = (props: EntityTagPickerProps) => {
const classes = useStyles();
const {
updateFilters,
@@ -65,7 +70,9 @@ export const EntityTagPicker = () => {
filter: filters.kind?.getCatalogFilters(),
});
return facets[facet].map(({ value }) => value);
return Object.fromEntries(
facets[facet].map(({ value, count }) => [value, count]),
);
}, [filters.kind]);
const queryParamTags = useMemo(
@@ -91,7 +98,7 @@ export const EntityTagPicker = () => {
});
}, [selectedTags, updateFilters]);
if (!availableTags?.length) return null;
if (!Object.keys(availableTags ?? {}).length) return null;
return (
<Box pb={1} pt={1}>
@@ -99,7 +106,7 @@ export const EntityTagPicker = () => {
Tags
<Autocomplete
multiple
options={availableTags}
options={Object.keys(availableTags ?? {})}
value={selectedTags}
onChange={(_: object, value: string[]) => setSelectedTags(value)}
renderOption={(option, { selected }) => (
@@ -111,7 +118,11 @@ export const EntityTagPicker = () => {
checked={selected}
/>
}
label={option}
label={
props.showCounts
? `${option} (${availableTags?.[option]})`
: option
}
/>
)}
size="small"
@@ -15,4 +15,7 @@
*/
export { EntityTagPicker } from './EntityTagPicker';
export type { CatalogReactEntityTagPickerClassKey } from './EntityTagPicker';
export type {
CatalogReactEntityTagPickerClassKey,
EntityTagPickerProps,
} from './EntityTagPicker';