Problem
Context: RHIDP-15167 (Entity Page Extensions), task 3.3
The VersionListCard entity card extension (plugins/boost/src/components/catalog/entity/VersionListCard.tsx) currently reads a single rhdh.io/ai-asset-version annotation and renders it as a badge with a "current" label. The entity-extensions spec requires it to list all versions of the same asset, highlight the current/recommended version, and let developers navigate between them.
AI assets in the catalog can have multiple version entities sharing the same logical asset identifier (e.g. code-review-skill at versions 1.0.0, 1.1.0, 1.2.0). The version list card should let developers see what versions exist and jump between them.
Expected behavior
The VersionListCard renders a list of all versions for the current AI asset, with navigation:
- Query versions — use the Backstage
catalogApiRef to find all entities that share the same rhdh.io/ai-asset-name annotation (or metadata.name base name) and have different rhdh.io/ai-asset-version values. This identifies sibling version entities.
- Render list — show each version as a row with:
- Version string (from
rhdh.io/ai-asset-version annotation)
- A "current" badge on the version matching the currently viewed entity
- A "recommended" badge if the entity has a
rhdh.io/ai-asset-recommended annotation set to true
- Navigation — clicking a non-current version row navigates to that version's catalog entity page using
entityHref() from utils/entityHelpers.ts.
- Single version — if only one version exists (or no sibling entities found), show just the current version badge with no navigation affordance (same as current behavior).
- No version — if the entity lacks
rhdh.io/ai-asset-version, return null.
Scope
- Workspace:
workspaces/boost
- Package:
@red-hat-developer-hub/backstage-plugin-boost (plugins/boost)
Files to modify
| File |
Change |
plugins/boost/src/components/catalog/entity/VersionListCard.tsx |
Replace single-badge rendering with a version list. Use useApi(catalogApiRef) to query sibling versions. Render each version as a clickable row (except current). Add "current" and "recommended" badges. Handle loading state while fetching siblings. |
plugins/boost/src/translations/ref.ts |
Add i18n keys: catalog.card.versionRecommended, catalog.card.versionNavigate (aria label for version link). |
fixtures/ai-catalog-fixtures.yaml |
Add a second version entity for one existing asset (e.g. code-review-skill at version 1.0.0 alongside the existing 1.2.0) so the multi-version behavior is exercisable in the dev app. |
New file
| File |
Content |
plugins/boost/src/components/catalog/entity/VersionListCard.test.tsx |
Unit tests (see below). |
Implementation details
Querying sibling versions
Use catalogApiRef.getEntities() with a filter on annotations:
const catalogApi = useApi(catalogApiRef);
const siblings = await catalogApi.getEntities({
filter: {
'metadata.annotations.rhdh.io/ai-asset-name': assetName,
},
});
Where assetName is derived from the current entity's rhdh.io/ai-asset-name annotation or, if that's not set, from metadata.name. Sort the results by version string (semver-aware if possible, falling back to lexicographic).
Wrap this in a useEffect + useState pattern (or useAsync from react-use if available in the workspace) to handle loading state.
Rendering
- Use BUI
Card / CardHeader / CardBody structure (same as current).
- Each version row:
Flex align="center" gap="2" containing the version string, optional badges, and a navigation icon for non-current versions.
- Current version:
Badge size="small" with the "current" label.
- Recommended version:
Badge size="small" variant="success" or similar distinguishing style.
- Non-current version rows: wrap in a clickable element (BUI
Link or Button variant="link") pointing to entityHref(siblingEntity).
- Loading: show a
Skeleton or spinner while sibling query is in flight.
- All text labels via
useTranslation().
Fixture entities
Add a second version of code-review-skill to fixtures/ai-catalog-fixtures.yaml:
apiVersion: backstage.io/v1alpha1
kind: AiResource
metadata:
name: code-review-skill-v1
namespace: default
description: Automated code review skill (legacy version)
annotations:
rhdh.io/ai-asset-category: skill
rhdh.io/ai-asset-version: '1.0.0'
rhdh.io/ai-asset-name: code-review-skill
rhdh.io/ai-asset-source: github
spec:
type: skill
lifecycle: production
owner: team-ai-platform
location:
type: git
target: https://github.com/example/code-review-skill
Also add a rhdh.io/ai-asset-name: code-review-skill annotation to the existing code-review-skill entity if not already present.
Tests
Add VersionListCard.test.tsx following the AdoptionCard.test.tsx pattern.
- Single version — entity with one version renders the version badge and "current" label, no navigation links.
- Multiple versions — mock
catalogApiRef.getEntities to return 3 sibling entities. Verify all versions render, current is marked, non-current have navigation links.
- Recommended badge — sibling with
rhdh.io/ai-asset-recommended: 'true' shows the recommended badge.
- No version annotation — entity without
rhdh.io/ai-asset-version returns null.
- Loading state — verify a loading indicator renders while the catalog query is in flight.
- Navigation link — clicking a non-current version triggers navigation to that entity's catalog page.
Notes
useApi and catalogApiRef are imported from @backstage/plugin-catalog-react. The catalogApiRef may need to be added to the plugin's dependencies if not already present.
- The
entityHref() helper already exists in utils/entityHelpers.ts and produces /catalog/:namespace/:kind/:name.
- This card is registered as
entity-card:boost/version-list in plugin.tsx with the isAiAsset filter. No registration changes needed.
- If
rhdh.io/ai-asset-name is not consistently set across fixture entities, fall back to metadata.name for sibling discovery. Document the annotation requirement.
Problem
Context: RHIDP-15167 (Entity Page Extensions), task 3.3
The
VersionListCardentity card extension (plugins/boost/src/components/catalog/entity/VersionListCard.tsx) currently reads a singlerhdh.io/ai-asset-versionannotation and renders it as a badge with a "current" label. The entity-extensions spec requires it to list all versions of the same asset, highlight the current/recommended version, and let developers navigate between them.AI assets in the catalog can have multiple version entities sharing the same logical asset identifier (e.g.
code-review-skillat versions1.0.0,1.1.0,1.2.0). The version list card should let developers see what versions exist and jump between them.Expected behavior
The
VersionListCardrenders a list of all versions for the current AI asset, with navigation:catalogApiRefto find all entities that share the samerhdh.io/ai-asset-nameannotation (ormetadata.namebase name) and have differentrhdh.io/ai-asset-versionvalues. This identifies sibling version entities.rhdh.io/ai-asset-versionannotation)rhdh.io/ai-asset-recommendedannotation set totrueentityHref()fromutils/entityHelpers.ts.rhdh.io/ai-asset-version, returnnull.Scope
workspaces/boost@red-hat-developer-hub/backstage-plugin-boost(plugins/boost)Files to modify
plugins/boost/src/components/catalog/entity/VersionListCard.tsxuseApi(catalogApiRef)to query sibling versions. Render each version as a clickable row (except current). Add "current" and "recommended" badges. Handle loading state while fetching siblings.plugins/boost/src/translations/ref.tscatalog.card.versionRecommended,catalog.card.versionNavigate(aria label for version link).fixtures/ai-catalog-fixtures.yamlcode-review-skillat version1.0.0alongside the existing1.2.0) so the multi-version behavior is exercisable in the dev app.New file
plugins/boost/src/components/catalog/entity/VersionListCard.test.tsxImplementation details
Querying sibling versions
Use
catalogApiRef.getEntities()with a filter on annotations:Where
assetNameis derived from the current entity'srhdh.io/ai-asset-nameannotation or, if that's not set, frommetadata.name. Sort the results by version string (semver-aware if possible, falling back to lexicographic).Wrap this in a
useEffect+useStatepattern (oruseAsyncfromreact-useif available in the workspace) to handle loading state.Rendering
Card/CardHeader/CardBodystructure (same as current).Flex align="center" gap="2"containing the version string, optional badges, and a navigation icon for non-current versions.Badge size="small"with the "current" label.Badge size="small" variant="success"or similar distinguishing style.LinkorButton variant="link") pointing toentityHref(siblingEntity).Skeletonor spinner while sibling query is in flight.useTranslation().Fixture entities
Add a second version of
code-review-skilltofixtures/ai-catalog-fixtures.yaml:Also add a
rhdh.io/ai-asset-name: code-review-skillannotation to the existingcode-review-skillentity if not already present.Tests
Add
VersionListCard.test.tsxfollowing theAdoptionCard.test.tsxpattern.catalogApiRef.getEntitiesto return 3 sibling entities. Verify all versions render, current is marked, non-current have navigation links.rhdh.io/ai-asset-recommended: 'true'shows the recommended badge.rhdh.io/ai-asset-versionreturns null.Notes
useApiandcatalogApiRefare imported from@backstage/plugin-catalog-react. ThecatalogApiRefmay need to be added to the plugin's dependencies if not already present.entityHref()helper already exists inutils/entityHelpers.tsand produces/catalog/:namespace/:kind/:name.entity-card:boost/version-listinplugin.tsxwith theisAiAssetfilter. No registration changes needed.rhdh.io/ai-asset-nameis not consistently set across fixture entities, fall back tometadata.namefor sibling discovery. Document the annotation requirement.