diff --git a/.changeset/fifty-berries-learn.md b/.changeset/fifty-berries-learn.md new file mode 100644 index 0000000000..647246a482 --- /dev/null +++ b/.changeset/fifty-berries-learn.md @@ -0,0 +1,37 @@ +--- +'@backstage/plugin-catalog': minor +--- + +Added new column `Label` to `CatalogTable.columns`, this new column allows you make use of labels from metadata. +For example: category and visibility are type of labels associated with API entity illustrated below. + +YAML code snippet for API entity + +```yaml +apiVersion: backstage.io/v1alpha1 +kind: API +metadata: + name: sample-api + description: API for sample + links: + - url: http://localhost:8080/swagger-ui.html + title: Swagger UI + tags: + - http + labels: + category: legacy + visibility: protected +``` + +Consumers can customise columns to include label column and show in api-docs list + +```typescript +const columns = [ + CatalogTable.columns.createNameColumn({ defaultKind: 'API' }), + CatalogTable.columns.createLabelColumn('category', { title: 'Category' }), + CatalogTable.columns.createLabelColumn('visibility', { + title: 'Visibility', + defaultValue: 'public', + }), +]; +``` diff --git a/plugins/catalog/api-report.md b/plugins/catalog/api-report.md index 377b62a1e6..71006b53b5 100644 --- a/plugins/catalog/api-report.md +++ b/plugins/catalog/api-report.md @@ -148,6 +148,15 @@ export const CatalogTable: { } | undefined, ): TableColumn; + createLabelColumn( + key: string, + options?: + | { + title?: string | undefined; + defaultValue?: string | undefined; + } + | undefined, + ): TableColumn; }>; }; diff --git a/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx b/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx index bd78cecaf0..bb2f302a37 100644 --- a/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx +++ b/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx @@ -331,4 +331,42 @@ describe('CatalogTable component', () => { expect(getByText('Should be rendered')).toBeInTheDocument(); }); + + it('should render the label column with customised title and value as specified', async () => { + const columns = [ + CatalogTable.columns.createNameColumn({ defaultKind: 'API' }), + CatalogTable.columns.createLabelColumn('category', { title: 'Category' }), + ]; + const entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'API', + metadata: { + name: 'APIWithLabel', + labels: { category: 'generic' }, + }, + }; + const expectedColumns = ['Name', 'Category', 'Actions']; + + const { getAllByRole, getByText } = await renderInTestApp( + + + + + , + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, + ); + + const columnHeader = getAllByRole('button').filter( + c => c.tagName === 'SPAN', + ); + const columnHeaderLabels = columnHeader.map(c => c.textContent); + expect(columnHeaderLabels).toEqual(expectedColumns); + + const labelCellValue = getByText('generic'); + expect(labelCellValue).toBeInTheDocument(); + }); }); diff --git a/plugins/catalog/src/components/CatalogTable/columns.tsx b/plugins/catalog/src/components/CatalogTable/columns.tsx index 19d160c0e2..7f3cd5ef82 100644 --- a/plugins/catalog/src/components/CatalogTable/columns.tsx +++ b/plugins/catalog/src/components/CatalogTable/columns.tsx @@ -162,4 +162,35 @@ export const columnFactories = Object.freeze({ searchable: true, }; }, + createLabelColumn( + key: string, + options?: { title?: string; defaultValue?: string }, + ): TableColumn { + return { + title: options?.title || 'Label', + field: 'entity.metadata.labels', + cellStyle: { + padding: '0px 16px 0px 20px', + }, + render: ({ entity }: { entity: Entity }) => { + const labels: Record | undefined = + entity.metadata?.labels; + const specifiedLabelValue = + (labels && labels[key]) || options?.defaultValue; + return ( + <> + {specifiedLabelValue && ( + + )} + + ); + }, + width: 'auto', + }; + }, });