feat(extensions): add catalog source filter and display to Extensions UI - #4070
Conversation
PR Summary by Qodofeat(extensions): add catalog source filter and display to Extensions UI
AI Description
Diagram
High-Level Assessment
Files changed (34)
|
Code Review by Qodo
Context used✅ Compliance rules (platform):
11 rules✅ Cross-repo context Explored:
repo: redhat-developer/rhdh (sha: 6bcb0141) Explored:
repo: redhat-developer/rhdh-local (sha: 2ae9e8c8) Not relevant to this PR:
redhat-developer/rhdh-chart Not relevant to this PR:
redhat-developer/rhdh-operator 1.
|
Add support for the `extensions.backstage.io/catalog-source` annotation on Plugin entities, enabling users to filter and identify plugins by their origin (e.g. Red Hat vs Community). RHIDP-15617 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
96d3c4f to
9cddedb
Compare
|
Important This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior. Changed Packages
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #4070 +/- ##
==========================================
+ Coverage 57.87% 57.88% +0.01%
==========================================
Files 2393 2396 +3
Lines 95985 96087 +102
Branches 26803 26825 +22
==========================================
+ Hits 55551 55620 +69
- Misses 38940 38973 +33
Partials 1494 1494
*This pull request uses carry forward flags. Click here to find out more. Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
CatalogSourceLabel calls useCatalogSourceConfig which requires configApiRef. The existing test setup did not provide it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
christoph-jerolimov
left a comment
There was a problem hiding this comment.
Thanks for that PR. Looks almost good, here are some suggestions:
- Don't add the annotation, that will be handled at runtime.
- Pass the complete plugin into
CatalogSourceBadgeandCatalogSourceLabel - Changelog includes common even if its not changed
- Backend includes a config.d.ts change that is only needed in the frontend
| description: Synchronize 3scale content into the Backstage catalog. | ||
| annotations: | ||
| extensions.backstage.io/pre-installed: 'true' | ||
| extensions.backstage.io/catalog-source: 'primary' |
There was a problem hiding this comment.
You don't need to add this annotation manually to all components, it will be automatically added at runtime (by the catalog module). You can verify that this works by looking into (software) catalog, select kind = Plugin and inspect with the three dot menu the entity.
Please remove this from all yaml files again:
| extensions.backstage.io/catalog-source: 'primary' |
| getCatalogSourceLabel, | ||
| } from '../hooks/useCatalogSourceConfig'; | ||
|
|
||
| export const CatalogSourceBadge = ({ sourceKey }: { sourceKey?: string }) => { |
There was a problem hiding this comment.
This requires that all code needs to know which annotation should be used. I think its easier if we pass the plugin to CatalogSourceBadge and do the "magic" inside this component.
| export const CatalogSourceBadge = ({ sourceKey }: { sourceKey?: string }) => { | |
| export const CatalogSourceBadge = ({ plugin }: { plugin: Plugin }) => { |
|
|
||
| if (!sourceKey) return null; | ||
|
|
||
| const meta = sourcesConfig[sourceKey]; |
There was a problem hiding this comment.
| const meta = sourcesConfig[sourceKey]; | |
| const meta = sourcesConfig[ExtensionsAnnotation.CATALOG_SOURCE]; |
| } from '../hooks/useCatalogSourceConfig'; | ||
| import { useTranslation } from '../hooks/useTranslation'; | ||
|
|
||
| export const CatalogSourceLabel = ({ sourceKey }: { sourceKey?: string }) => { |
There was a problem hiding this comment.
Use a plugin as input here to make the prop easier and the calling component doesn't need to extract the annotation.
| export const CatalogSourceLabel = ({ sourceKey }: { sourceKey?: string }) => { | |
| export const CatalogSourceLabel = ({ plugin }: { plugin: Plugin }) => { |
| <CatalogSourceLabel | ||
| sourceKey={ | ||
| plugin.metadata?.annotations?.[ | ||
| ExtensionsAnnotation.CATALOG_SOURCE | ||
| ] | ||
| } | ||
| /> |
There was a problem hiding this comment.
| <CatalogSourceLabel | |
| sourceKey={ | |
| plugin.metadata?.annotations?.[ | |
| ExtensionsAnnotation.CATALOG_SOURCE | |
| ] | |
| } | |
| /> | |
| <CatalogSourceLabel plugin={plugin} /> |
| <CatalogSourceBadge | ||
| sourceKey={ | ||
| plugin.metadata?.annotations?.[ | ||
| ExtensionsAnnotation.CATALOG_SOURCE | ||
| ] | ||
| } | ||
| /> |
There was a problem hiding this comment.
Please pass the plugin into the CatalogSourceBadge and handle the annotation extraction in that component
| <CatalogSourceBadge | |
| sourceKey={ | |
| plugin.metadata?.annotations?.[ | |
| ExtensionsAnnotation.CATALOG_SOURCE | |
| ] | |
| } | |
| /> | |
| <CatalogSourceBadge plugin={plugin} /> |
|
|
||
| /** | ||
| * Metadata for catalog sources used to label and filter plugins by origin. | ||
| * Keys correspond to the `extensions.backstage.io/catalog-source` annotation value. | ||
| * @visibility frontend | ||
| */ | ||
| catalogSources?: { | ||
| [sourceKey: string]: { | ||
| /** | ||
| * Display label for this catalog source. | ||
| * @visibility frontend | ||
| */ | ||
| label: string; | ||
|
|
||
| /** | ||
| * Optional description shown as a tooltip. | ||
| * @visibility frontend | ||
| */ | ||
| description?: string; | ||
|
|
||
| /** | ||
| * Optional badge text shown on the plugin card in list view. | ||
| * @visibility frontend | ||
| */ | ||
| badge?: string; | ||
| }; | ||
| }; |
There was a problem hiding this comment.
The backend doesn't need this config.d.ts change. Please revert this.
| @@ -0,0 +1,6 @@ | |||
| --- | |||
| '@red-hat-developer-hub/backstage-plugin-extensions': minor | |||
| '@red-hat-developer-hub/backstage-plugin-extensions-common': minor | |||
There was a problem hiding this comment.
there was no change in commons package?!
| '@red-hat-developer-hub/backstage-plugin-extensions-common': minor |
| export const getCatalogSourceLabel = ( | ||
| sourceKey: string, | ||
| sourcesConfig: Record<string, CatalogSourceMeta>, | ||
| ): string => { | ||
| return sourcesConfig[sourceKey]?.label ?? sourceKey; | ||
| }; |
There was a problem hiding this comment.
remove sourceKey here and directly use the annotation const
- Remove manually added catalog-source annotations from example YAMLs (annotations are added at runtime by the catalog module) - Refactor CatalogSourceBadge and CatalogSourceLabel to accept plugin prop and extract annotation internally - Update getCatalogSourceLabel to accept plugin and use annotation const - Revert config.d.ts changes in extensions-backend (not needed) - Remove extensions-common from changeset (no changes in that package) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… and filter - Guard CatalogSourceLabel with isExtensionsPackage check since plugin can be ExtensionsPlugin | ExtensionsPackage - Use direct config lookup in CatalogSourceFilter instead of getCatalogSourceLabel (which now expects a plugin object) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| permission: | ||
| # setting this to `false` will disable permissions | ||
| enabled: true | ||
| enabled: false |
There was a problem hiding this comment.
Please revert the app config change
| value={plugin.spec?.support?.provider} | ||
| /> | ||
|
|
||
| {!isExtensionsPackage(plugin) && ( |
There was a problem hiding this comment.
Use a positive check isExtensionsPlugin instead
…-config permission Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|







Summary
extensions.backstage.io/catalog-sourceannotation support to label and filter plugins by origin (e.g. Red Hat, Community)CatalogSourceBadgechip on plugin cards andCatalogSourceLabelin the detail view, with tooltip descriptions driven byextensions.catalogSourcesapp-config?filter=catalog-source=<value>)config.d.tswith@visibility frontendto ensure config reaches the browser bundleResolves: RHIDP-15617
Changes
extensions-common/src/annotations.ts— newCATALOG_SOURCEenum entryplugins/extensions/config.d.ts(new),plugins/extensions-backend/config.d.tssrc/hooks/useCatalogSourceConfig.ts(new)CatalogSourceBadge.tsx,CatalogSourceLabel.tsx,CatalogSourceChip(new)ExtensionsPluginFilter.tsx,useFilteredPlugins.ts,useFilteredPluginFacet.tsExtensionsPluginContent.tsx— catalog source chip in header, positiveisExtensionsPlugintype guardsPluginCard.tsx— title ellipsis with tooltip, categories as pill chips, author + badge row layoutCategoryLinkButton.tsx— pill-shaped category buttonsuseCatalogSourceConfig.test.tsx(5 tests),CatalogSourceFilter.test.tsx(4 tests),PluginCard.test.tsxupdatedref.ts,de.ts,es.ts,fr.ts,it.ts,ja.tscatalog-sourceannotationmockPlugins.ts,mockExtensions.tsapp-config.yaml—extensions.catalogSourcessectionreport.api.md,report-alpha.api.mdTest plan
yarn build:allpasses🤖 Generated with Claude Code