Skip to content

feat(extensions): add catalog source filter and display to Extensions UI - #4070

Open
rohitratannagar wants to merge 8 commits into
redhat-developer:mainfrom
rohitratannagar:feat/RHIDP-15617-catalog-source-filter
Open

feat(extensions): add catalog source filter and display to Extensions UI#4070
rohitratannagar wants to merge 8 commits into
redhat-developer:mainfrom
rohitratannagar:feat/RHIDP-15617-catalog-source-filter

Conversation

@rohitratannagar

@rohitratannagar rohitratannagar commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add extensions.backstage.io/catalog-source annotation support to label and filter plugins by origin (e.g. Red Hat, Community)
  • New CatalogSourceBadge chip on plugin cards and CatalogSourceLabel in the detail view, with tooltip descriptions driven by extensions.catalogSources app-config
  • New sidebar filter for catalog source with URL query parameter persistence (?filter=catalog-source=<value>)
  • Frontend config.d.ts with @visibility frontend to ensure config reaches the browser bundle
  • Updated example plugin YAMLs, mock fixtures, and translation files (de, es, fr, it, ja)
  • Plugin card and detail view UI enhancements: title truncation with tooltip, category pills layout, catalog source chip in detail header

Resolves: RHIDP-15617

Changes

Area Files
Annotation extensions-common/src/annotations.ts — new CATALOG_SOURCE enum entry
Config schema plugins/extensions/config.d.ts (new), plugins/extensions-backend/config.d.ts
Config hook src/hooks/useCatalogSourceConfig.ts (new)
UI components CatalogSourceBadge.tsx, CatalogSourceLabel.tsx, CatalogSourceChip (new)
Filter ExtensionsPluginFilter.tsx, useFilteredPlugins.ts, useFilteredPluginFacet.ts
Detail view ExtensionsPluginContent.tsx — catalog source chip in header, positive isExtensionsPlugin type guards
Card view PluginCard.tsx — title ellipsis with tooltip, categories as pill chips, author + badge row layout
Category styling CategoryLinkButton.tsx — pill-shaped category buttons
Tests useCatalogSourceConfig.test.tsx (5 tests), CatalogSourceFilter.test.tsx (4 tests), PluginCard.test.tsx updated
Translations ref.ts, de.ts, es.ts, fr.ts, it.ts, ja.ts
Examples 8 plugin YAML files with catalog-source annotation
Mocks mockPlugins.ts, mockExtensions.ts
App config app-config.yamlextensions.catalogSources section
API reports report.api.md, report-alpha.api.md

Test plan

  • All 22 tests pass (13 PluginCard + 5 useCatalogSourceConfig + 4 CatalogSourceFilter)
  • yarn build:all passes
  • Prettier clean
  • Lint-staged passed on commit
  • Verify badge renders on plugin cards in list view
  • Verify tooltip on hover shows description from config
  • Verify catalog source label shown in plugin detail view
  • Verify sidebar filter lists distinct catalog sources
  • Verify filter narrows plugin list and persists in URL

🤖 Generated with Claude Code

@rhdh-qodo-merge

Copy link
Copy Markdown

PR Summary by Qodo

feat(extensions): add catalog source filter and display to Extensions UI

✨ Enhancement 🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Introduce extensions.backstage.io/catalog-source annotation to label plugins by origin (e.g. Red
 Hat, Community).
• Add CatalogSourceBadge/CatalogSourceLabel UI components and a sidebar filter with URL
 persistence (?filter=catalog-source=).
• Add frontend-visible extensions.catalogSources config schema plus example YAMLs, mock fixtures,
 and translations for de/es/fr/it/ja.
• Add unit tests for the new config hook and filter component (9 new tests) and update PluginCard
 tests.
Diagram

graph TD
  A["Plugin entity annotation"] --> B["useCatalogSourceConfig hook"]
  C["app-config.yaml catalogSources"] --> B
  B --> D["CatalogSourceBadge"]
  B --> E["CatalogSourceLabel"]
  B --> F["CatalogSourceFilter"]
  F --> G["useFilteredPluginFacet / useFilteredPlugins"]
  G --> H["URL query parameter"]
  subgraph Legend
    direction LR
    _cfg[(Config)] ~~~ _comp([Component]) ~~~ _hook{{Hook/Logic}}
  end
Loading
High-Level Assessment

The PR follows the existing plugin conventions closely: it mirrors the pattern already used for category/support-type filters (annotation → facet hook → CustomSelectFilter → URL persistence) and reuses the established config-schema/@visibility frontend approach used elsewhere in the plugin. This is the natural, low-risk extension point and no better alternative architecture was evident.

Files changed (34) +652 / -2

Enhancement (9) +259 / -0
annotations.tsAdd CATALOG_SOURCE annotation enum value +1/-0

Add CATALOG_SOURCE annotation enum value

• Introduces 'ExtensionsAnnotation.CATALOG_SOURCE' mapped to 'extensions.backstage.io/catalog-source'.

workspaces/extensions/plugins/extensions-common/src/annotations.ts

CatalogSourceBadge.tsxAdd CatalogSourceBadge component +45/-0

Add CatalogSourceBadge component

• New chip component that renders a plugin's catalog source badge with an optional tooltip description, falling back to config label or raw key.

workspaces/extensions/plugins/extensions/src/components/CatalogSourceBadge.tsx

CatalogSourceLabel.tsxAdd CatalogSourceLabel component +58/-0

Add CatalogSourceLabel component

• New component rendering the catalog source label with heading and optional tooltip description in the plugin detail view.

workspaces/extensions/plugins/extensions/src/components/CatalogSourceLabel.tsx

ExtensionsPluginContent.tsxRender CatalogSourceLabel in plugin detail view +10/-0

Render CatalogSourceLabel in plugin detail view

• Wires up 'CatalogSourceLabel' in the plugin detail sidebar, reading the catalog-source annotation from plugin metadata.

workspaces/extensions/plugins/extensions/src/components/ExtensionsPluginContent.tsx

ExtensionsPluginFilter.tsxAdd CatalogSourceFilter to sidebar filters +45/-0

Add CatalogSourceFilter to sidebar filters

• Introduces a new 'CatalogSourceFilter' component that lists distinct catalog sources with counts, config-driven labels/tooltips, and wires it into 'ExtensionsPluginFilter'.

workspaces/extensions/plugins/extensions/src/components/ExtensionsPluginFilter.tsx

PluginCard.tsxRender CatalogSourceBadge on plugin card +9/-0

Render CatalogSourceBadge on plugin card

• Adds 'CatalogSourceBadge' to the plugin card, reading the catalog-source annotation from plugin metadata.

workspaces/extensions/plugins/extensions/src/components/PluginCard.tsx

useCatalogSourceConfig.tsAdd useCatalogSourceConfig hook and label helper +54/-0

Add useCatalogSourceConfig hook and label helper

• New hook reads 'extensions.catalogSources' from the config API into a memoized map, plus a 'getCatalogSourceLabel' helper that falls back to the raw key when unconfigured.

workspaces/extensions/plugins/extensions/src/hooks/useCatalogSourceConfig.ts

useFilteredPluginFacet.tsSupport catalog-source facet filtering +24/-0

Support catalog-source facet filtering

• Adds catalog-source filter exclusion logic, filters plugins by selected catalog sources, and extracts facet values for the 'metadata.annotations.catalog-source' facet.

workspaces/extensions/plugins/extensions/src/hooks/useFilteredPluginFacet.ts

useFilteredPlugins.tsApply catalog-source filter to plugin list +13/-0

Apply catalog-source filter to plugin list

• Filters the main plugin list by selected catalog-source query parameter values.

workspaces/extensions/plugins/extensions/src/hooks/useFilteredPlugins.ts

Tests (5) +285 / -2
mockExtensions.tsAdd catalog-source annotations to dev mock plugins +9/-0

Add catalog-source annotations to dev mock plugins

• Adds catalog-source annotations to techdocs, catalog, and scaffolder mock plugin entries for local dev preview.

workspaces/extensions/plugins/extensions/dev/data/mockExtensions.ts

mockPlugins.tsAdd catalog-source annotations to test fixtures +6/-0

Add catalog-source annotations to test fixtures

• Adds catalog-source annotations to plugin-1 and plugin-2 fixture data used across tests.

workspaces/extensions/plugins/extensions/src/fixtures/mockPlugins.ts

CatalogSourceFilter.test.tsxAdd tests for catalog source sidebar filter +147/-0

Add tests for catalog source sidebar filter

• New test suite covering rendering with sources, hiding when no sources exist, label mapping from config, and fallback to raw annotation values.

workspaces/extensions/plugins/extensions/src/components/CatalogSourceFilter.test.tsx

PluginCard.test.tsxUpdate PluginCard tests with config API provider +5/-2

Update PluginCard tests with config API provider

• Adds a mocked 'configApiRef' provider to support the new 'CatalogSourceBadge' dependency in 'PluginCard'.

workspaces/extensions/plugins/extensions/src/components/PluginCard.test.tsx

useCatalogSourceConfig.test.tsxAdd tests for useCatalogSourceConfig hook +118/-0

Add tests for useCatalogSourceConfig hook

• New test suite covering empty config, parsed multi-source config, sources with only required fields, and the 'getCatalogSourceLabel' helper.

workspaces/extensions/plugins/extensions/src/hooks/useCatalogSourceConfig.test.tsx

Documentation (8) +16 / -0
report.api.mdUpdate API report with CATALOG_SOURCE enum entry +2/-0

Update API report with CATALOG_SOURCE enum entry

• Regenerated API report reflecting the new 'ExtensionsAnnotation.CATALOG_SOURCE' enum value.

workspaces/extensions/plugins/extensions-common/report.api.md

report-alpha.api.mdUpdate alpha API report with new translation keys +2/-0

Update alpha API report with new translation keys

• Regenerated API report reflecting new 'metadata.catalogSource' and 'search.catalogSource' translation keys.

workspaces/extensions/plugins/extensions/report-alpha.api.md

de.tsAdd German translations for catalog source +2/-0

Add German translations for catalog source

• Adds 'search.catalogSource' and 'metadata.catalogSource' German translation strings.

workspaces/extensions/plugins/extensions/src/alpha/translations/de.ts

es.tsAdd Spanish translations for catalog source +2/-0

Add Spanish translations for catalog source

• Adds 'search.catalogSource' and 'metadata.catalogSource' Spanish translation strings.

workspaces/extensions/plugins/extensions/src/alpha/translations/es.ts

fr.tsAdd French translations for catalog source +2/-0

Add French translations for catalog source

• Adds 'search.catalogSource' and 'metadata.catalogSource' French translation strings.

workspaces/extensions/plugins/extensions/src/alpha/translations/fr.ts

it.tsAdd Italian translations for catalog source +2/-0

Add Italian translations for catalog source

• Adds 'search.catalogSource' and 'metadata.catalogSource' Italian translation strings.

workspaces/extensions/plugins/extensions/src/alpha/translations/it.ts

ja.tsAdd Japanese translations for catalog source +2/-0

Add Japanese translations for catalog source

• Adds 'search.catalogSource' and 'metadata.catalogSource' Japanese translation strings.

workspaces/extensions/plugins/extensions/src/alpha/translations/ja.ts

ref.tsAdd reference translation keys for catalog source +2/-0

Add reference translation keys for catalog source

• Adds 'search.catalogSource' and 'metadata.catalogSource' reference (English) translation keys used by all locales.

workspaces/extensions/plugins/extensions/src/alpha/translations/ref.ts

Other (12) +92 / -0
app-config.yamlAdd example catalogSources config section +9/-0

Add example catalogSources config section

• Adds sample 'primary' and 'community' catalog source entries with label, description, and badge fields under 'extensions.catalogSources'.

workspaces/extensions/app-config.yaml

3scale.yamlTag 3scale plugin with catalog-source annotation +1/-0

Tag 3scale plugin with catalog-source annotation

• Adds 'extensions.backstage.io/catalog-source: 'primary'' annotation.

workspaces/extensions/examples/plugins/3scale.yaml

bulk-import.yamlTag bulk-import plugin with catalog-source annotation +1/-0

Tag bulk-import plugin with catalog-source annotation

• Adds 'extensions.backstage.io/catalog-source: 'primary'' annotation.

workspaces/extensions/examples/plugins/bulk-import.yaml

extensions.yamlTag extensions plugin with catalog-source annotation +1/-0

Tag extensions plugin with catalog-source annotation

• Adds 'extensions.backstage.io/catalog-source: 'community'' annotation.

workspaces/extensions/examples/plugins/extensions.yaml

keycloak.yamlTag keycloak plugin with catalog-source annotation +1/-0

Tag keycloak plugin with catalog-source annotation

• Adds 'extensions.backstage.io/catalog-source: 'primary'' annotation.

workspaces/extensions/examples/plugins/keycloak.yaml

quay.yamlTag quay plugin with catalog-source annotation +1/-0

Tag quay plugin with catalog-source annotation

• Adds 'extensions.backstage.io/catalog-source: 'primary'' annotation.

workspaces/extensions/examples/plugins/quay.yaml

search.yamlTag search plugin with catalog-source annotation +1/-0

Tag search plugin with catalog-source annotation

• Adds 'extensions.backstage.io/catalog-source: 'community'' annotation.

workspaces/extensions/examples/plugins/search.yaml

tekton.yamlTag tekton plugin with catalog-source annotation +1/-0

Tag tekton plugin with catalog-source annotation

• Adds 'extensions.backstage.io/catalog-source: 'community'' annotation.

workspaces/extensions/examples/plugins/tekton.yaml

topology.yamlTag topology plugin with catalog-source annotation +1/-0

Tag topology plugin with catalog-source annotation

• Adds 'extensions.backstage.io/catalog-source: 'primary'' annotation.

workspaces/extensions/examples/plugins/topology.yaml

config.d.tsAdd catalogSources schema to extensions-backend config +27/-0

Add catalogSources schema to extensions-backend config

• Defines the 'extensions.catalogSources' config schema with label, description, and badge fields marked '@visibility frontend'.

workspaces/extensions/plugins/extensions-backend/config.d.ts

config.d.tsAdd new frontend config schema for catalogSources +46/-0

Add new frontend config schema for catalogSources

• New file declaring the 'extensions.catalogSources' config interface with '@visibility frontend' so the config is bundled to the browser.

workspaces/extensions/plugins/extensions/config.d.ts

package.jsonRegister config.d.ts as plugin configSchema +2/-0

Register config.d.ts as plugin configSchema

• Adds 'configSchema' field pointing to 'config.d.ts' and includes it in published 'files'.

workspaces/extensions/plugins/extensions/package.json

@rhdh-qodo-merge

rhdh-qodo-merge Bot commented Jul 28, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 🔗 Cross-repo conflicts (1) 📜 Skill insights (0)

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

Grey Divider


Action required

1. Detail tests lack config API ✓ Resolved 🐞 Bug ☼ Reliability
Description
Adding CatalogSourceLabel makes every ExtensionsPluginContent render require configApiRef, but its
existing test provider does not register that API. All tests in ExtensionsPluginContent.test.tsx
now fail during rendering before reaching their assertions.
Code

workspaces/extensions/plugins/extensions/src/components/ExtensionsPluginContent.tsx[665]

+            <CatalogSourceLabel
Relevance

●●● Strong

Deterministic test regression with a trivial missing MockConfigApi fix.

PR-#3896

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
CatalogSourceLabel calls the config hook before checking sourceKey, and the hook immediately
resolves configApiRef. The detail-view test provider only registers extensions, error, and
translation APIs, while the analogous PluginCard test provider was updated by this PR to register an
empty MockConfigApi.

workspaces/extensions/plugins/extensions/src/components/CatalogSourceLabel.tsx[27-34]
workspaces/extensions/plugins/extensions/src/hooks/useCatalogSourceConfig.ts[27-34]
workspaces/extensions/plugins/extensions/src/components/ExtensionsPluginContent.test.tsx[110-123]
workspaces/extensions/plugins/extensions/src/components/PluginCard.test.tsx[59-64]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The detail-view test suite does not provide the config API now required by `CatalogSourceLabel`, causing deterministic render-time failures.

## Issue Context
`CatalogSourceLabel` invokes `useCatalogSourceConfig` even when no source annotation exists, and that hook unconditionally calls `useApi(configApiRef)`. Update the shared detail-view test provider with an empty `MockConfigApi`, as already done for PluginCard tests.

## Fix Focus Areas
- workspaces/extensions/plugins/extensions/src/components/ExtensionsPluginContent.test.tsx[110-123]
- workspaces/extensions/plugins/extensions/src/components/CatalogSourceLabel.tsx[27-34]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Selected source shows raw key 🐞 Bug ≡ Correctness
Description
CatalogSourceFilter uses configured labels for options but passes URL-derived selections whose label
is the raw annotation value. After selecting or restoring primary, the control displays primary
instead of the configured Red Hat label.
Code

workspaces/extensions/plugins/extensions/src/components/ExtensionsPluginFilter.tsx[217]

+      selectedItems={filter.current}
Relevance

●●● Strong

Clear UI inconsistency contradicts configured-label intent and has a local deterministic fix.

PR-#3690

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The filter creates options with configured labels, but useQueryArrayFilter reconstructs selected
entries with the raw value as their label. CustomSelectFilter then renders the controlled selected
entries through getOptionLabel={option => option.label}, exposing the raw key.

workspaces/extensions/plugins/extensions/src/components/ExtensionsPluginFilter.tsx[192-218]
workspaces/extensions/plugins/extensions/src/hooks/useQueryArrayFilter.ts[36-50]
workspaces/extensions/plugins/extensions/src/shared-components/CustomSelectFilter.tsx[77-80]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Catalog-source selections are reconstructed from the URL with the raw source key as their label, so the controlled autocomplete displays raw keys rather than configured labels.

## Issue Context
The available `items` contain configured labels, while `filter.current` contains `{ label: value, value }`. Resolve selected values against `items` before passing them to `CustomSelectFilter`, retaining a raw-value fallback for unconfigured sources.

## Fix Focus Areas
- workspaces/extensions/plugins/extensions/src/components/ExtensionsPluginFilter.tsx[192-218]
- workspaces/extensions/plugins/extensions/src/hooks/useQueryArrayFilter.ts[36-50]
- workspaces/extensions/plugins/extensions/src/components/CatalogSourceFilter.test.tsx[103-125]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Catalog metadata missing downstream 🔗 Cross-repo conflict ≡ Correctness
Description
The primary and community metadata is added only to the workspace development config, while RHDH
and rhdh-local enable the published dynamic plugin without extensions.catalogSources. Their
Extensions UI will therefore display raw source keys and omit configured descriptions/tooltips
instead of showing the intended Red Hat and Community metadata.
Code

workspaces/extensions/app-config.yaml[R154-162]

+  catalogSources:
+    primary:
+      label: Red Hat
+      description: Plugins provided and supported by Red Hat
+      badge: Red Hat
+    community:
+      label: Community
+      description: Community-maintained plugins
+      badge: Community
Relevance

●● Moderate

Downstream defaults may be intentional operator configuration; no close repository precedent
resolves ownership.

PR-#3944

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The PR defines the source metadata in the workspace app config, but the frontend hook explicitly
returns an empty map when that config is absent and then falls back to the raw source key. The
plugin's packaged dynamic configuration contains only route/translation wiring, while the pinned
RHDH and rhdh-local integration configurations enable the Extensions frontend/backend without
supplying extensions.catalogSources.

workspaces/extensions/app-config.yaml[153-162]
workspaces/extensions/plugins/extensions/app-config.dynamic.yaml[1-20]
workspaces/extensions/plugins/extensions/src/hooks/useCatalogSourceConfig.ts[27-53]
External repo: redhat-developer/rhdh, dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-extensions/package.json [25-31]
External repo: redhat-developer/rhdh, app-config.dynamic-plugins.yaml [597-614]
External repo: redhat-developer/rhdh-local, configs/dynamic-plugins/dynamic-plugins.yaml [34-47]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description

The catalog-source defaults are currently defined only in the Extensions workspace development `app-config.yaml`. RHDH and rhdh-local consume the published dynamic plugin without this configuration, causing labels to fall back to raw annotation keys and descriptions/tooltips to disappear.

## Issue Context

Publish the `primary` and `community` catalog-source metadata through configuration consumed by dynamic-plugin deployments, or coordinate equivalent additions to the effective RHDH and rhdh-local app configurations. Preserve the development configuration as needed, but ensure the published integration receives the same defaults.

## Fix Focus Areas

- workspaces/extensions/plugins/extensions/app-config.dynamic.yaml[1-20]
- workspaces/extensions/app-config.yaml[153-162]
- workspaces/extensions/plugins/extensions/src/hooks/useCatalogSourceConfig.ts[27-53]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

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>
@rhdh-qodo-merge rhdh-qodo-merge Bot added documentation Improvements or additions to documentation enhancement New feature or request Tests labels Jul 28, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@rohitratannagar
rohitratannagar force-pushed the feat/RHIDP-15617-catalog-source-filter branch from 96d3c4f to 9cddedb Compare July 28, 2026 22:35
@rhdh-gh-app

rhdh-gh-app Bot commented Jul 28, 2026

Copy link
Copy Markdown

Important

This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior.

Changed Packages

Package Name Package Path Changeset Bump Current Version
@red-hat-developer-hub/backstage-plugin-extensions workspaces/extensions/plugins/extensions minor v0.19.1

@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 69.29825% with 35 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.88%. Comparing base (e03b281) to head (1e4186f).
⚠️ Report is 25 commits behind head on main.
✅ All tests successful. No failed tests found.

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              
Flag Coverage Δ *Carryforward flag
adoption-insights 84.54% <ø> (ø) Carriedforward from 86eaaf1
ai-integrations 69.06% <ø> (ø) Carriedforward from 86eaaf1
app-defaults 69.79% <ø> (ø) Carriedforward from 86eaaf1
augment 46.67% <ø> (ø) Carriedforward from 86eaaf1
boost 76.77% <ø> (ø) Carriedforward from 86eaaf1
bulk-import 72.55% <ø> (ø) Carriedforward from 86eaaf1
cost-management 13.55% <ø> (ø) Carriedforward from 86eaaf1
dcm 60.72% <ø> (ø) Carriedforward from 86eaaf1
extensions 56.77% <69.29%> (+0.28%) ⬆️
global-floating-action-button 71.18% <ø> (ø) Carriedforward from 86eaaf1
global-header 62.17% <ø> (ø) Carriedforward from 86eaaf1
homepage 47.46% <ø> (ø) Carriedforward from 86eaaf1
install-dynamic-plugins 56.77% <ø> (ø) Carriedforward from 86eaaf1
intelligent-assistant 74.24% <ø> (ø) Carriedforward from 86eaaf1
konflux 91.98% <ø> (ø) Carriedforward from 86eaaf1
lightspeed 69.02% <ø> (ø) Carriedforward from 86eaaf1
mcp-integrations 83.40% <ø> (ø) Carriedforward from 86eaaf1
orchestrator 66.79% <ø> (ø) Carriedforward from 86eaaf1
quickstart 65.04% <ø> (ø) Carriedforward from 86eaaf1
sandbox 79.56% <ø> (ø) Carriedforward from 86eaaf1
scorecard 84.94% <ø> (ø) Carriedforward from 86eaaf1
theme 87.90% <ø> (ø) Carriedforward from 86eaaf1
translations 5.12% <ø> (ø) Carriedforward from 86eaaf1
x2a 79.31% <ø> (ø) Carriedforward from 86eaaf1

*This pull request uses carry forward flags. Click here to find out more.


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e03b281...1e4186f. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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 christoph-jerolimov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for that PR. Looks almost good, here are some suggestions:

  1. Don't add the annotation, that will be handled at runtime.
  2. Pass the complete plugin into CatalogSourceBadge and CatalogSourceLabel
  3. Changelog includes common even if its not changed
  4. 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'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

Suggested change
extensions.backstage.io/catalog-source: 'primary'

getCatalogSourceLabel,
} from '../hooks/useCatalogSourceConfig';

export const CatalogSourceBadge = ({ sourceKey }: { sourceKey?: string }) => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
export const CatalogSourceBadge = ({ sourceKey }: { sourceKey?: string }) => {
export const CatalogSourceBadge = ({ plugin }: { plugin: Plugin }) => {


if (!sourceKey) return null;

const meta = sourcesConfig[sourceKey];

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const meta = sourcesConfig[sourceKey];
const meta = sourcesConfig[ExtensionsAnnotation.CATALOG_SOURCE];

} from '../hooks/useCatalogSourceConfig';
import { useTranslation } from '../hooks/useTranslation';

export const CatalogSourceLabel = ({ sourceKey }: { sourceKey?: string }) => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a plugin as input here to make the prop easier and the calling component doesn't need to extract the annotation.

Suggested change
export const CatalogSourceLabel = ({ sourceKey }: { sourceKey?: string }) => {
export const CatalogSourceLabel = ({ plugin }: { plugin: Plugin }) => {

Comment on lines +665 to +671
<CatalogSourceLabel
sourceKey={
plugin.metadata?.annotations?.[
ExtensionsAnnotation.CATALOG_SOURCE
]
}
/>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<CatalogSourceLabel
sourceKey={
plugin.metadata?.annotations?.[
ExtensionsAnnotation.CATALOG_SOURCE
]
}
/>
<CatalogSourceLabel plugin={plugin} />

Comment on lines +199 to +205
<CatalogSourceBadge
sourceKey={
plugin.metadata?.annotations?.[
ExtensionsAnnotation.CATALOG_SOURCE
]
}
/>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please pass the plugin into the CatalogSourceBadge and handle the annotation extraction in that component

Suggested change
<CatalogSourceBadge
sourceKey={
plugin.metadata?.annotations?.[
ExtensionsAnnotation.CATALOG_SOURCE
]
}
/>
<CatalogSourceBadge plugin={plugin} />

Comment on lines +33 to +59

/**
* 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;
};
};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there was no change in commons package?!

Suggested change
'@red-hat-developer-hub/backstage-plugin-extensions-common': minor

Comment on lines +49 to +54
export const getCatalogSourceLabel = (
sourceKey: string,
sourcesConfig: Record<string, CatalogSourceMeta>,
): string => {
return sourcesConfig[sourceKey]?.label ?? sourceKey;
};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove sourceKey here and directly use the annotation const

rohitratannagar and others added 2 commits July 30, 2026 02:59
- 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>
Comment thread workspaces/extensions/app-config.yaml Outdated
permission:
# setting this to `false` will disable permissions
enabled: true
enabled: false

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert the app config change

value={plugin.spec?.support?.provider}
/>

{!isExtensionsPackage(plugin) && (

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a positive check isExtensionsPlugin instead

rohitratannagar and others added 3 commits July 30, 2026 13:23
…-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>
@sonarqubecloud

Copy link
Copy Markdown

@rohitratannagar

rohitratannagar commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

UI Enhancement of the plugin card

Before

Screenshot 2026-07-30 at 10 41 07 PM

After

Screenshot 2026-07-30 at 10 22 55 PM Screenshot 2026-07-30 at 10 33 01 PM

multiple categories (example)

Screenshot 2026-07-30 at 9 48 27 PM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request Tests workspace/extensions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants