diff --git a/.changeset/gorgeous-pillows-retire.md b/.changeset/gorgeous-pillows-retire.md new file mode 100644 index 0000000000..d6d4009ac2 --- /dev/null +++ b/.changeset/gorgeous-pillows-retire.md @@ -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 diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index 6e0ba235b7..1ae82f702b 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -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 { diff --git a/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.test.tsx b/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.test.tsx index 2be521203f..78bdde1994 100644 --- a/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.test.tsx +++ b/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.test.tsx @@ -28,7 +28,9 @@ const tags = ['tag1', 'tag2', 'tag3', 'tag4']; describe('', () => { 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('', () => { ]); }); + it('renders tags with counts', async () => { + const rendered = render( + + + + + , + ); + 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'] }; diff --git a/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx b/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx index 39895f229d..25f02e8adc 100644 --- a/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx +++ b/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx @@ -49,7 +49,12 @@ const icon = ; const checkedIcon = ; /** @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 ( @@ -99,7 +106,7 @@ export const EntityTagPicker = () => { Tags 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" diff --git a/plugins/catalog-react/src/components/EntityTagPicker/index.ts b/plugins/catalog-react/src/components/EntityTagPicker/index.ts index c982d33df0..28c8c844f8 100644 --- a/plugins/catalog-react/src/components/EntityTagPicker/index.ts +++ b/plugins/catalog-react/src/components/EntityTagPicker/index.ts @@ -15,4 +15,7 @@ */ export { EntityTagPicker } from './EntityTagPicker'; -export type { CatalogReactEntityTagPickerClassKey } from './EntityTagPicker'; +export type { + CatalogReactEntityTagPickerClassKey, + EntityTagPickerProps, +} from './EntityTagPicker';