Merge pull request #13911 from al06/catalog-table-enhancement-with-label-column

feat: enhance catalog-plugin table with label column
This commit is contained in:
Johan Haals
2022-10-03 13:50:14 +02:00
committed by GitHub
4 changed files with 115 additions and 0 deletions
+37
View File
@@ -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',
}),
];
```
+9
View File
@@ -148,6 +148,15 @@ export const CatalogTable: {
}
| undefined,
): TableColumn<CatalogTableRow>;
createLabelColumn(
key: string,
options?:
| {
title?: string | undefined;
defaultValue?: string | undefined;
}
| undefined,
): TableColumn<CatalogTableRow>;
}>;
};
@@ -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(
<ApiProvider apis={mockApis}>
<MockEntityListContextProvider value={{ entities: [entity] }}>
<CatalogTable columns={columns} />
</MockEntityListContextProvider>
</ApiProvider>,
{
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();
});
});
@@ -162,4 +162,35 @@ export const columnFactories = Object.freeze({
searchable: true,
};
},
createLabelColumn(
key: string,
options?: { title?: string; defaultValue?: string },
): TableColumn<CatalogTableRow> {
return {
title: options?.title || 'Label',
field: 'entity.metadata.labels',
cellStyle: {
padding: '0px 16px 0px 20px',
},
render: ({ entity }: { entity: Entity }) => {
const labels: Record<string, string> | undefined =
entity.metadata?.labels;
const specifiedLabelValue =
(labels && labels[key]) || options?.defaultValue;
return (
<>
{specifiedLabelValue && (
<Chip
key={specifiedLabelValue}
label={specifiedLabelValue}
size="small"
variant="outlined"
/>
)}
</>
);
},
width: 'auto',
};
},
});