feat(catalog): add Kind field to About Card

Signed-off-by: Johan Persson <johanopersson@gmail.com>
This commit is contained in:
Johan Persson
2026-03-25 11:53:07 +01:00
parent 7d5a3a2567
commit c193ef1f9f
6 changed files with 34 additions and 12 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog': patch
---
Added Kind field to the About Card. Tags moved before Type and Lifecycle, Kind placed after them. A new `aboutCard.kindField.label` translation key was added.
+1
View File
@@ -67,6 +67,7 @@ export const catalogTranslationRef: TranslationRef<
readonly 'aboutCard.systemField.label': 'System';
readonly 'aboutCard.parentComponentField.value': 'No Parent Component';
readonly 'aboutCard.parentComponentField.label': 'Parent Component';
readonly 'aboutCard.kindField.label': 'Kind';
readonly 'aboutCard.typeField.label': 'Type';
readonly 'aboutCard.lifecycleField.label': 'Lifecycle';
readonly 'aboutCard.tagsField.value': 'No Tags';
+1
View File
@@ -251,6 +251,7 @@ export const catalogTranslationRef: TranslationRef<
readonly 'aboutCard.systemField.label': 'System';
readonly 'aboutCard.parentComponentField.value': 'No Parent Component';
readonly 'aboutCard.parentComponentField.label': 'Parent Component';
readonly 'aboutCard.kindField.label': 'Kind';
readonly 'aboutCard.typeField.label': 'Type';
readonly 'aboutCard.lifecycleField.label': 'Lifecycle';
readonly 'aboutCard.tagsField.value': 'No Tags';
+3
View File
@@ -61,6 +61,9 @@ export const catalogTranslationRef = createTranslationRef({
label: 'Parent Component',
value: 'No Parent Component',
},
kindField: {
label: 'Kind',
},
typeField: {
label: 'Type',
},
@@ -83,6 +83,8 @@ describe('<AboutContent />', () => {
expect(screen.getByText('Type').nextSibling).toHaveTextContent('t');
expect(screen.getByText('Lifecycle')).toBeInTheDocument();
expect(screen.getByText('Lifecycle').nextSibling).toHaveTextContent('l');
expect(screen.getByText('Kind')).toBeInTheDocument();
expect(screen.getByText('Kind').nextSibling).toHaveTextContent('Unknown');
expect(screen.getByText('Tags')).toBeInTheDocument();
expect(screen.getByText('Tags').nextSibling).toHaveTextContent('tag-1');
});
@@ -111,6 +113,7 @@ describe('<AboutContent />', () => {
expect(screen.queryByText('Parent Component')).not.toBeInTheDocument();
expect(screen.queryByText('Type')).not.toBeInTheDocument();
expect(screen.queryByText('Lifecycle')).not.toBeInTheDocument();
expect(screen.getByText('Kind')).toBeInTheDocument();
});
});
@@ -362,7 +365,9 @@ describe('<AboutContent />', () => {
expect(screen.getByText('Owner').nextSibling).toHaveTextContent(
'user:guest',
);
expect(screen.queryByText('Domain')).not.toBeInTheDocument();
expect(
screen.queryByRole('heading', { name: 'Domain' }),
).not.toBeInTheDocument();
expect(screen.queryByText('System')).not.toBeInTheDocument();
expect(screen.queryByText('Parent Component')).not.toBeInTheDocument();
expect(screen.queryByText('Type')).not.toBeInTheDocument();
@@ -389,7 +394,9 @@ describe('<AboutContent />', () => {
expect(screen.getByText('Owner').nextSibling).toHaveTextContent(
'No Owner',
);
expect(screen.queryByText('Domain')).not.toBeInTheDocument();
expect(
screen.queryByRole('heading', { name: 'Domain' }),
).not.toBeInTheDocument();
expect(screen.queryByText('System')).not.toBeInTheDocument();
expect(screen.queryByText('Parent Component')).not.toBeInTheDocument();
expect(screen.queryByText('Type')).not.toBeInTheDocument();
@@ -617,7 +624,9 @@ describe('<AboutContent />', () => {
expect(screen.getByText('Domain').nextSibling).toHaveTextContent(
'domain',
);
expect(screen.queryByText('System')).not.toBeInTheDocument();
expect(
screen.queryByRole('heading', { name: 'System' }),
).not.toBeInTheDocument();
expect(screen.queryByText('Parent Component')).not.toBeInTheDocument();
expect(screen.queryByText('Type')).not.toBeInTheDocument();
expect(screen.queryByText('Lifecycle')).not.toBeInTheDocument();
@@ -648,7 +657,9 @@ describe('<AboutContent />', () => {
expect(screen.getByText('Domain').nextSibling).toHaveTextContent(
'No Domain',
);
expect(screen.queryByText('System')).not.toBeInTheDocument();
expect(
screen.queryByRole('heading', { name: 'System' }),
).not.toBeInTheDocument();
expect(screen.queryByText('Parent Component')).not.toBeInTheDocument();
expect(screen.queryByText('Type')).not.toBeInTheDocument();
expect(screen.queryByText('Lifecycle')).not.toBeInTheDocument();
@@ -178,6 +178,15 @@ export function AboutContent(props: AboutContentProps) {
/>
</AboutField>
)}
<AboutField
label={t('aboutCard.tagsField.label')}
value={t('aboutCard.tagsField.value')}
>
{(entity?.metadata?.tags || []).map(tag => (
<Chip key={tag} size="small" label={tag} />
))}
</AboutField>
<AboutField label={t('aboutCard.kindField.label')} value={entity.kind} />
{(isAPI ||
isComponent ||
isResource ||
@@ -198,14 +207,6 @@ export function AboutContent(props: AboutContentProps) {
value={entity?.spec?.lifecycle as string}
/>
)}
<AboutField
label={t('aboutCard.tagsField.label')}
value={t('aboutCard.tagsField.value')}
>
{(entity?.metadata?.tags || []).map(tag => (
<Chip key={tag} size="small" label={tag} />
))}
</AboutField>
{isLocation && (entity?.spec?.targets || entity?.spec?.target) && (
<Grid.Item colSpan={columns}>
<AboutField label={t('aboutCard.targetsField.label')}>