@red-hat-developer-hub/backstage-plugin-scorecard 2.8.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.md +146 -37
  3. package/dist/alpha.d.ts +115 -79
  4. package/dist/alpha.esm.js +1 -49
  5. package/dist/alpha.esm.js.map +1 -1
  6. package/dist/{alpha/blueprints → blueprints}/ScorecardLayoutBlueprint.esm.js +1 -1
  7. package/dist/blueprints/ScorecardLayoutBlueprint.esm.js.map +1 -0
  8. package/dist/components/AggregatedMetricCards/AggregatedMetricCard.esm.js +18 -21
  9. package/dist/components/AggregatedMetricCards/AggregatedMetricCard.esm.js.map +1 -1
  10. package/dist/components/AggregatedMetricCards/StatusGroupedCard/StatusGroupedCardComponent.esm.js.map +1 -1
  11. package/dist/components/AggregatedMetricCards/{AverageCard → WeightedStatusScoreCard}/DonutChartTooltipContent.esm.js +3 -3
  12. package/dist/components/AggregatedMetricCards/WeightedStatusScoreCard/DonutChartTooltipContent.esm.js.map +1 -0
  13. package/dist/components/AggregatedMetricCards/WeightedStatusScoreCard/TooltipContent.esm.js.map +1 -0
  14. package/dist/components/AggregatedMetricCards/{AverageCard/AverageCardComponent.esm.js → WeightedStatusScoreCard/WeightedStatusScoreCardComponent.esm.js} +19 -19
  15. package/dist/components/AggregatedMetricCards/WeightedStatusScoreCard/WeightedStatusScoreCardComponent.esm.js.map +1 -0
  16. package/dist/components/AggregatedMetricCards/{AverageCard/AverageCardPieCenterLabel.esm.js → WeightedStatusScoreCard/WeightedStatusScoreCardPieCenterLabel.esm.js} +5 -5
  17. package/dist/components/AggregatedMetricCards/WeightedStatusScoreCard/WeightedStatusScoreCardPieCenterLabel.esm.js.map +1 -0
  18. package/dist/components/AggregatedMetricCards/components/CardLegendContent.esm.js.map +1 -1
  19. package/dist/components/AggregatedMetricCards/components/CardTooltip.esm.js.map +1 -1
  20. package/dist/components/MetricGroupCard/DataSourcesDialog.esm.js +146 -0
  21. package/dist/components/MetricGroupCard/DataSourcesDialog.esm.js.map +1 -0
  22. package/dist/components/MetricGroupCard/DataSourcesDialogColumns.esm.js +184 -0
  23. package/dist/components/MetricGroupCard/DataSourcesDialogColumns.esm.js.map +1 -0
  24. package/dist/components/MetricGroupCard/MetricGroupCard.esm.js +100 -0
  25. package/dist/components/MetricGroupCard/MetricGroupCard.esm.js.map +1 -0
  26. package/dist/components/MetricGroupCard/MetricGroupCardMenu.esm.js +68 -0
  27. package/dist/components/MetricGroupCard/MetricGroupCardMenu.esm.js.map +1 -0
  28. package/dist/components/MetricGroupCard/StatusIcon.esm.js +23 -0
  29. package/dist/components/MetricGroupCard/StatusIcon.esm.js.map +1 -0
  30. package/dist/components/MetricGroupCard/ThresholdBucketTile.esm.js +81 -0
  31. package/dist/components/MetricGroupCard/ThresholdBucketTile.esm.js.map +1 -0
  32. package/dist/components/MetricGroupCard/ThresholdLegend.esm.js +100 -0
  33. package/dist/components/MetricGroupCard/ThresholdLegend.esm.js.map +1 -0
  34. package/dist/components/MetricGroupCard/thresholdBucketUtils.esm.js +74 -0
  35. package/dist/components/MetricGroupCard/thresholdBucketUtils.esm.js.map +1 -0
  36. package/dist/components/Scorecard/EntityScorecardContent.esm.js +9 -6
  37. package/dist/components/Scorecard/EntityScorecardContent.esm.js.map +1 -1
  38. package/dist/components/Scorecard/Scorecard.esm.js +3 -3
  39. package/dist/components/Scorecard/Scorecard.esm.js.map +1 -1
  40. package/dist/components/Scorecard/ScorecardEntityContentGridView.esm.js +61 -148
  41. package/dist/components/Scorecard/ScorecardEntityContentGridView.esm.js.map +1 -1
  42. package/dist/components/ScorecardHomepageSection/ScorecardHomepageCard.esm.js +1 -2
  43. package/dist/components/ScorecardHomepageSection/ScorecardHomepageCard.esm.js.map +1 -1
  44. package/dist/components/ScorecardIcon/ScorecardIcon.esm.js +2 -2
  45. package/dist/components/ScorecardIcon/ScorecardIcon.esm.js.map +1 -1
  46. package/dist/components/ScorecardPage/ScorecardPage.esm.js +1 -2
  47. package/dist/components/ScorecardPage/ScorecardPage.esm.js.map +1 -1
  48. package/dist/{alpha/extensions → extensions}/api.esm.js +1 -1
  49. package/dist/extensions/api.esm.js.map +1 -0
  50. package/dist/{alpha/extensions → extensions}/entityTab.esm.js +3 -3
  51. package/dist/extensions/entityTab.esm.js.map +1 -0
  52. package/dist/{alpha/extensions → extensions}/homePageCards.esm.js +26 -42
  53. package/dist/extensions/homePageCards.esm.js.map +1 -0
  54. package/dist/extensions/scorecardLayoutExtensions.esm.js +15 -0
  55. package/dist/extensions/scorecardLayoutExtensions.esm.js.map +1 -0
  56. package/dist/{alpha/extensions → extensions}/scorecardPage.esm.js +2 -2
  57. package/dist/extensions/scorecardPage.esm.js.map +1 -0
  58. package/dist/index.d.ts +228 -23
  59. package/dist/index.esm.js +39 -8
  60. package/dist/index.esm.js.map +1 -1
  61. package/dist/legacy.d.ts +35 -0
  62. package/dist/legacy.esm.js +12 -0
  63. package/dist/legacy.esm.js.map +1 -0
  64. package/dist/translations/de.esm.js +46 -35
  65. package/dist/translations/de.esm.js.map +1 -1
  66. package/dist/translations/es.esm.js +46 -35
  67. package/dist/translations/es.esm.js.map +1 -1
  68. package/dist/translations/fr.esm.js +46 -35
  69. package/dist/translations/fr.esm.js.map +1 -1
  70. package/dist/translations/it.esm.js +46 -35
  71. package/dist/translations/it.esm.js.map +1 -1
  72. package/dist/translations/ja.esm.js +46 -35
  73. package/dist/translations/ja.esm.js.map +1 -1
  74. package/dist/translations/ref.esm.js +40 -21
  75. package/dist/translations/ref.esm.js.map +1 -1
  76. package/dist/utils/translationUtils.esm.js +6 -1
  77. package/dist/utils/translationUtils.esm.js.map +1 -1
  78. package/package.json +35 -26
  79. package/dist/alpha/blueprints/ScorecardLayoutBlueprint.esm.js.map +0 -1
  80. package/dist/alpha/extensions/api.esm.js.map +0 -1
  81. package/dist/alpha/extensions/entityTab.esm.js.map +0 -1
  82. package/dist/alpha/extensions/homePageCards.esm.js.map +0 -1
  83. package/dist/alpha/extensions/scorecardLayoutExtensions.esm.js +0 -21
  84. package/dist/alpha/extensions/scorecardLayoutExtensions.esm.js.map +0 -1
  85. package/dist/alpha/extensions/scorecardPage.esm.js.map +0 -1
  86. package/dist/components/AggregatedMetricCards/AverageCard/AverageCardComponent.esm.js.map +0 -1
  87. package/dist/components/AggregatedMetricCards/AverageCard/AverageCardPieCenterLabel.esm.js.map +0 -1
  88. package/dist/components/AggregatedMetricCards/AverageCard/DonutChartTooltipContent.esm.js.map +0 -1
  89. package/dist/components/AggregatedMetricCards/AverageCard/TooltipContent.esm.js.map +0 -1
  90. package/dist/components/ScorecardStylesProvider.esm.js +0 -12
  91. package/dist/components/ScorecardStylesProvider.esm.js.map +0 -1
  92. package/dist/types/index.d-DLQMegMp.d.ts +0 -113
  93. /package/dist/components/AggregatedMetricCards/{AverageCard → WeightedStatusScoreCard}/TooltipContent.esm.js +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,72 @@
1
1
  # @red-hat-developer-hub/backstage-plugin-scorecard
2
2
 
3
+ ## 3.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - f4b8bd4: **BREAKING**: Graduated the New Frontend System (NFS) scorecard plugin to the stable entry point and simplified NFS feature registration.
8
+
9
+ - NFS APIs move from `./alpha` to `.`; OFS APIs move to `./legacy` only (not re-exported from the main entry); translations remain at `./alpha`.
10
+ - `scorecardCatalogModule` and `scorecardHomeModule` are removed. Entity tab, layout, and homepage widgets are now provided by the default `scorecardPlugin`. Keep only `scorecardTranslationsModule` as a separate app module.
11
+ - Extension IDs move from the `catalog` / `home` namespaces to `scorecard` (for example `entity-content:catalog/entity-content-scorecard` → `entity-content:scorecard/entity-content-scorecard`). Update any `app.extensions` config accordingly. See the plugin README migration notes.
12
+
13
+ - 6ea1575: **BREAKING**: Rename aggregation KPI type `average` to `weightedStatusScore`.
14
+
15
+ ### App config
16
+
17
+ - `scorecard.aggregationKPIs.*.type`: `average` → `weightedStatusScore`
18
+
19
+ ### `GET /aggregations/:aggregationId` API
20
+
21
+ - `metadata.aggregationType`: `average` → `weightedStatusScore`
22
+ - `result.averageScore` → `result.weightedStatusScore`
23
+ - `result.averageWeightedSum` → `result.weightedStatusSum`
24
+ - `result.averageMaxPossible` → `result.weightedStatusMaxPossible`
25
+
26
+ ### Frontend translations (`metric.*`)
27
+
28
+ Update any scorecard translation overrides that used the old `average*` keys:
29
+
30
+ - `metric.averageCenterTooltipTotalLabel` → `metric.weightedStatusScoreCenterTooltipTotalLabel`
31
+ - `metric.averageCenterTooltipMaxLabel` → `metric.weightedStatusScoreCenterTooltipMaxLabel`
32
+ - `metric.averageCenterTooltipBreakdownRow_one` / `_other` → `metric.weightedStatusScoreCenterTooltipBreakdownRow_one` / `_other`
33
+ - `metric.averageLegendTooltipEntitiesEach_one` / `_other` → `metric.weightedStatusScoreLegendTooltipEntitiesEach_one` / `_other`
34
+ - `metric.averageLegendTooltipRowTotal` → `metric.weightedStatusScoreLegendTooltipRowTotal`
35
+
36
+ The `averageLegendTooltip*` keys served the removed side-legend tooltip; the center donut tooltip uses the `weightedStatusScoreCenterTooltip*` keys (including per-status breakdown rows).
37
+
38
+ ### UI `data-testid` values
39
+
40
+ Update downstream e2e selectors that targeted the weighted-status-score card center label:
41
+
42
+ - `average-card-center-percent` → `weighted-status-score-card-center-percent`
43
+ - `average-card-center-percent-hit-area` → `weighted-status-score-card-center-percent-hit-area`
44
+
45
+ - dfb90b7: **BREAKING**: Standardize all metric and provider IDs from `snake_case` to `lowerCamelCase`.
46
+
47
+ This aligns metric IDs with the naming convention used in `app-config.yaml` and the planned Scorecard design. For example, `github.open_prs` is now `github.openPRs`, `sonarqube.quality_gate` is now `sonarqube.qualityGate`, and `dependabot.alerts_critical` is now `dependabot.alertsCritical`.
48
+
49
+ If you reference metric IDs in your `app-config.yaml` (e.g., in `metricId` fields or plugin schedule config keys), update them to use `lowerCamelCase`.
50
+
51
+ ### Minor Changes
52
+
53
+ - 50447ac: Backstage version bump to v1.52.0
54
+ - f024236: Introduce a MetricGroupCard component that aggregates related metrics into threshold-based bucket tiles with a filterable data sources dialog. ScorecardEntityContentGridView to render grouped metrics as MetricGroupCards and ungrouped metrics as individual Scorecard cards using a Masonry layout. Add i18n keys across all supported locales and comprehensive unit tests for all new components.
55
+
56
+ ### Patch Changes
57
+
58
+ - 83d8a47: Removed unused `ScorecardStylesProvider` component and `@mui/styles` dependency. JSS class-name isolation is no longer needed after the MUI5 migration.
59
+ - 963c98c: optimized how scorecard homepage is loaded
60
+ - Updated dependencies [50447ac]
61
+ - Updated dependencies [6ea1575]
62
+ - @red-hat-developer-hub/backstage-plugin-scorecard-common@3.0.0
63
+
64
+ ## 2.8.1
65
+
66
+ ### Patch Changes
67
+
68
+ - @red-hat-developer-hub/backstage-plugin-scorecard-common@2.8.1
69
+
3
70
  ## 2.8.0
4
71
 
5
72
  ### Minor Changes
package/README.md CHANGED
@@ -2,12 +2,16 @@
2
2
 
3
3
  The Scorecard plugin provides a configurable framework to visualize Key Performance Indicators (KPIs) in Backstage. This frontend plugin integrates with the Scorecard backend to deliver Scorecards.
4
4
 
5
- The plugin supports both the **legacy** Backstage frontend and the **New Frontend System (NFS)**. Use the main package for legacy apps and the `/alpha` export for NFS apps. For NFS, the plugin currently provides three modules: a catalog module for the Scorecard entity tab, a home module for homepage widgets, and a translations module.
5
+ The plugin supports both the **legacy** Backstage frontend and the **New Frontend System (NFS)**. NFS is the primary package entry point. OFS (legacy) exports are available only at `./legacy`. Translations remain available at `./alpha`.
6
+
7
+ For NFS, register the default `scorecardPlugin` plus `scorecardTranslationsModule`. The plugin itself contributes the Scorecard page, entity tab, layout, and homepage widgets (no separate catalog/home modules).
8
+
6
9
  **Features:**
7
10
 
8
11
  - **Entity scorecard tab** — View scorecard metrics on catalog entity pages (components, websites, etc.).
9
- - **Scorecard homepage card** — Show aggregated KPIs on the home page (e.g. GitHub open PRs, Jira open issues). Supports **`statusGrouped`** (multi-slice pie) and **`average`** (weighted health donut) KPI types configured under **`scorecard.aggregationKPIs`**.
12
+ - **Scorecard homepage card** — Show aggregated KPIs on the home page (e.g. GitHub open PRs, Jira open issues). Supports **`statusGrouped`** (multi-slice pie) and **`weightedStatusScore`** (weighted health donut) KPI types configured under **`scorecard.aggregationKPIs`**.
10
13
  - **Scorecard Entities page** — Drill down from an aggregated metric to see the list of entities contributing to that metric, with entity-level values and status, so you can identify services impacting the KPI and investigate issues.
14
+ - **Metric group cards (grid layout)** — Group related metrics into cards with threshold bucket tiles, a filterable/sortable data sources dialog, and a Masonry grid layout. Enabled via app-config.yaml.
11
15
 
12
16
  ## Getting started
13
17
 
@@ -43,21 +47,18 @@ yarn workspace app-legacy add @red-hat-developer-hub/backstage-plugin-scorecard
43
47
  yarn workspace app add @red-hat-developer-hub/backstage-plugin-scorecard
44
48
  ```
45
49
 
46
- 2. Register the plugin in `packages/app/src/App.tsx` using the **alpha** export:
50
+ 2. Register the plugin in `packages/app/src/App.tsx`:
47
51
 
48
52
  ```tsx
49
53
  // In packages/app/src/App.tsx
50
54
  import { createApp } from '@backstage/frontend-defaults';
51
- import {
52
- scorecardHomeModule,
55
+ import scorecardPlugin, {
53
56
  scorecardTranslationsModule,
54
- scorecardCatalogModule,
55
- } from '@red-hat-developer-hub/backstage-plugin-scorecard/alpha';
57
+ } from '@red-hat-developer-hub/backstage-plugin-scorecard';
56
58
 
57
59
  const app = createApp({
58
60
  features: [
59
- scorecardHomeModule,
60
- scorecardCatalogModule,
61
+ scorecardPlugin,
61
62
  scorecardTranslationsModule,
62
63
  // ... other plugins
63
64
  ],
@@ -71,7 +72,7 @@ yarn workspace app-legacy add @red-hat-developer-hub/backstage-plugin-scorecard
71
72
  ```yaml
72
73
  app:
73
74
  extensions:
74
- - entity-content:catalog/entity-content-scorecard:
75
+ - entity-content:scorecard/entity-content-scorecard:
75
76
  config:
76
77
  allowedFilters:
77
78
  - kind: component
@@ -122,7 +123,46 @@ To align with the legacy EntityPage (Scorecard on component pages and default en
122
123
 
123
124
  5. Start the NFS app (e.g. `yarn start`), go to **Catalog**, open an entity. The **Scorecard** tab appears for entities that match your `allowedFilters` (or all entities if the extension config is omitted or empty).
124
125
 
125
- 6. (Optional) Enable homepage Scorecard widgets by adding `scorecardHomeModule` to app features (see step 2) and configuring home page extensions in `app-config.yaml`:
126
+ 6. (Optional) Enable the **grid layout** with metric group cards. The grid layout extension is disabled by default. Enable it and define `groups` in `app-config.yaml` to organize metrics into themed cards:
127
+
128
+ ```yaml
129
+ app:
130
+ extensions:
131
+ - scorecard-layout:scorecard/scorecard-entity-layout-grid:
132
+ config:
133
+ groups:
134
+ codeQuality:
135
+ title: 'Code Quality'
136
+ description: 'SonarQube code quality metrics'
137
+ metrics:
138
+ - sonarqube.reliabilityIssues
139
+ - sonarqube.codeCoverage
140
+ - sonarqube.securityIssues
141
+ operations:
142
+ title: 'Operations'
143
+ metrics:
144
+ - github.openPrs
145
+ - jira.openIssues
146
+ ```
147
+
148
+ **Groups config schema:**
149
+
150
+ | Field | Type | Required | Description |
151
+ | ------------- | ---------- | -------- | ---------------------------------------------------- |
152
+ | `title` | `string` | Yes | Display title for the group card. |
153
+ | `description` | `string` | No | Optional description shown below the title. |
154
+ | `metrics` | `string[]` | Yes | Ordered list of metric IDs to include in this group. |
155
+
156
+ **Behavior:**
157
+
158
+ - Metrics listed in `groups` are rendered as **MetricGroupCard** components. Each card shows threshold bucket tiles (e.g. Passing, Warning, Failing) with counts. Clicking a tile opens a **data sources dialog** pre-filtered to that status.
159
+ - The data sources dialog displays a sortable, filterable table with columns: Plugin, Check, Value, Status, and Last Synced. A threshold legend allows toggling visibility by status.
160
+ - Metrics **not** listed in any group are rendered as individual Scorecard cards below the group cards.
161
+ - All cards are arranged in a responsive **Masonry** grid (1 column on mobile, 2 on tablet, 3 on desktop).
162
+ - If `groups` is empty or omitted, the grid layout falls back to the default `EntityScorecardContent` view (individual cards for all metrics).
163
+ - When multiple layout extensions are enabled, the Scorecard tab renders a toggle to switch between them.
164
+
165
+ 7. (Optional) Enable homepage Scorecard widgets by configuring home page extensions in `app-config.yaml` (widgets are registered by `scorecardPlugin`):
126
166
 
127
167
  ```yaml
128
168
  app:
@@ -215,27 +255,96 @@ To align with the legacy EntityPage (Scorecard on component pages and default en
215
255
 
216
256
  ##### Modules and extensions (NFS)
217
257
 
218
- The following modules and extensions are available from `@red-hat-developer-hub/backstage-plugin-scorecard/alpha` for NFS apps:
258
+ The following modules and extensions are available from `@red-hat-developer-hub/backstage-plugin-scorecard` for NFS apps:
219
259
 
220
260
  **Modules**
221
261
 
222
- | Module | Description |
223
- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
224
- | `scorecardHomeModule` | Registers Scorecard homepage widgets for the home plugin (`AggregatedCardWithDeprecatedMetricId`, `AggregatedCardWithDefaultAggregation`, `AggregatedCardWithJiraOpenIssues`, `AggregatedCardWithGithubOpenPrs`, `AggregatedCardWithGithubFilecheckLicense`, `AggregatedCardWithGithubFilecheckCodeowners` and `AggregatedCardWithGithubOpenPrsWeighted`). |
225
- | `scorecardCatalogModule` | Registers the Scorecard entity tab with the catalog plugin. Add to your app's `features`. Which entities show the tab is configured via `app.extensions` (see step 3). |
226
- | `scorecardTranslationsModule` | Registers Scorecard translations with the app. Add to your app's `features`. |
262
+ | Module | Description |
263
+ | ----------------------------- | ---------------------------------------------------------------------------- |
264
+ | `scorecardTranslationsModule` | Registers Scorecard translations with the app. Add to your app's `features`. |
265
+
266
+ The default `scorecardPlugin` registers the Scorecard page, API, entity tab, layout, and homepage widgets.
267
+
268
+ **Extension IDs**
269
+
270
+ | Extension ID | Description |
271
+ | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
272
+ | `api:scorecard` | Scorecard API (auto-discovered when the plugin is installed). |
273
+ | `page:scorecard` | Scorecard entities / drill-down page. |
274
+ | `entity-content:scorecard/entity-content-scorecard` | Scorecard tab on catalog entity pages. Configure with `allowedFilters` in `app.extensions` to limit by kind and optionally type. |
275
+ | `scorecard-layout:scorecard/scorecard-entity-layout-grid` | Grid layout with metric group cards (disabled by default). Enable via `app.extensions` and define `groups` (see step 6). |
276
+ | `home-page-widget:scorecard/scorecard-deprecated-metric-id` | Homepage widget using deprecated `metricId` (Jira open issues). |
277
+ | `home-page-widget:scorecard/scorecard-default-aggregation` | Homepage widget using default aggregation (GitHub open PRs). |
278
+ | `home-page-widget:scorecard/scorecard-jira-open-issues` | Homepage widget for Jira open blocking tickets. |
279
+ | `home-page-widget:scorecard/scorecard-github-open-prs` | Homepage widget for GitHub open PRs. |
280
+ | `home-page-widget:scorecard/scorecard-github-filecheck-license` | Homepage widget for file check "License". |
281
+ | `home-page-widget:scorecard/scorecard-github-filecheck-codeowners` | Homepage widget for file check "Codeowners". |
282
+ | `home-page-widget:scorecard/scorecard-github-open-prs-weighted` | Homepage widget for weighted GitHub open PRs health. |
283
+
284
+ ##### Migration notes (NFS graduation)
285
+
286
+ If you previously imported Scorecard NFS APIs from `/alpha` and registered separate catalog/home modules, update as follows.
287
+
288
+ **1. Features registration**
289
+
290
+ ```diff
291
+ - import scorecardPlugin, {
292
+ - scorecardCatalogModule,
293
+ - scorecardHomeModule,
294
+ - scorecardTranslationsModule,
295
+ - } from '@red-hat-developer-hub/backstage-plugin-scorecard/alpha';
296
+ + import scorecardPlugin, {
297
+ + scorecardTranslationsModule,
298
+ + } from '@red-hat-developer-hub/backstage-plugin-scorecard';
299
+
300
+ features: [
301
+ scorecardPlugin,
302
+ - scorecardCatalogModule,
303
+ - scorecardHomeModule,
304
+ scorecardTranslationsModule,
305
+ ]
306
+ ```
227
307
 
228
- **Extensions**
308
+ `scorecardCatalogModule` and `scorecardHomeModule` are removed. Entity tab and homepage widgets are provided by `scorecardPlugin` directly.
309
+
310
+ **2. `app.extensions` IDs**
311
+
312
+ Extension IDs now use the `scorecard` plugin namespace (not `catalog` / `home`):
313
+
314
+ | Old ID | New ID |
315
+ | ------------------------------------------------------------- | ------------------------------------------------------------------ |
316
+ | `entity-content:catalog/entity-content-scorecard` | `entity-content:scorecard/entity-content-scorecard` |
317
+ | `scorecard-layout:catalog/scorecard-entity-layout-grid` | `scorecard-layout:scorecard/scorecard-entity-layout-grid` |
318
+ | `home-page-widget:home/scorecard-deprecated-metric-id` | `home-page-widget:scorecard/scorecard-deprecated-metric-id` |
319
+ | `home-page-widget:home/scorecard-default-aggregation` | `home-page-widget:scorecard/scorecard-default-aggregation` |
320
+ | `home-page-widget:home/scorecard-jira-open-issues` | `home-page-widget:scorecard/scorecard-jira-open-issues` |
321
+ | `home-page-widget:home/scorecard-github-open-prs` | `home-page-widget:scorecard/scorecard-github-open-prs` |
322
+ | `home-page-widget:home/scorecard-github-filecheck-license` | `home-page-widget:scorecard/scorecard-github-filecheck-license` |
323
+ | `home-page-widget:home/scorecard-github-filecheck-codeowners` | `home-page-widget:scorecard/scorecard-github-filecheck-codeowners` |
324
+ | `home-page-widget:home/scorecard-github-open-prs-weighted` | `home-page-widget:scorecard/scorecard-github-open-prs-weighted` |
325
+
326
+ Example:
327
+
328
+ ```diff
329
+ app:
330
+ extensions:
331
+ - - entity-content:catalog/entity-content-scorecard:
332
+ + - entity-content:scorecard/entity-content-scorecard:
333
+ config:
334
+ allowedFilters:
335
+ - kind: component
336
+ ```
229
337
 
230
- - `api:scorecard` Scorecard API (provided by the plugin; auto-discovered when the plugin is installed).
231
- - `entity-content:catalog/entity-content-scorecard` — Scorecard tab on catalog entity pages. Configure with `allowedFilters` in `app.extensions` to limit by kind and optionally type.
232
- - `home-page-widget:home/scorecard-deprecated-metric-id` — Homepage widget using deprecated metricId property (Jira open issues).
233
- - `home-page-widget:home/scorecard-default-aggregation` — Homepage widget using default aggregation config (GitHub open PRs).
234
- - `home-page-widget:home/scorecard-jira-open-issues` Homepage widget showing Jira open blocking tickets.
235
- - `home-page-widget:home/scorecard-github-open-prs` — Homepage widget showing GitHub open PRs.
236
- - `home-page-widget:home/scorecard-github-filecheck-license` - Homepage widget showing file check "License".
237
- - `home-page-widget:home/scorecard-github-filecheck-codeowners` - Homepage widget showing file check "Codeowners".
238
- - `home-page-widget:home/scorecard-github-open-prs-weighted` - Homepage widget showing average GitHub open PRs.
338
+ Homepage widget **layout** config under `home-page-layout:home/dynamic-homepage-layout` (widget names like `AggregatedCardWithGithubOpenPrs`) is unchanged; only the extension IDs above move namespaces.
339
+
340
+ **3. Legacy (OFS) imports**
341
+
342
+ OFS components, the OFS plugin, and status icons are available only from `./legacy` (not re-exported from the main entry):
343
+
344
+ ```diff
345
+ - import { EntityScorecardContent } from '@red-hat-developer-hub/backstage-plugin-scorecard';
346
+ + import { EntityScorecardContent } from '@red-hat-developer-hub/backstage-plugin-scorecard/legacy';
347
+ ```
239
348
 
240
349
  #### Legacy app
241
350
 
@@ -248,7 +357,7 @@ The following modules and extensions are available from `@red-hat-developer-hub/
248
357
  2. Add the Scorecard tab to the entity overview in `packages/app-legacy/src/components/catalog/EntityPage.tsx` (or your legacy app's equivalent):
249
358
 
250
359
  ```tsx
251
- import { EntityScorecardContent } from '@red-hat-developer-hub/backstage-plugin-scorecard';
360
+ import { EntityScorecardContent } from '@red-hat-developer-hub/backstage-plugin-scorecard/legacy';
252
361
 
253
362
  const scorecardRoute = (
254
363
  <EntityLayout.Route path="/scorecard" title="Scorecard">
@@ -293,13 +402,13 @@ The following modules and extensions are available from `@red-hat-developer-hub/
293
402
  3. (Optional) Add Scorecard homepage cards to your home page:
294
403
 
295
404
  ```tsx
296
- import { ScorecardHomepageCard } from '@red-hat-developer-hub/backstage-plugin-scorecard';
405
+ import { ScorecardHomepageCard } from '@red-hat-developer-hub/backstage-plugin-scorecard/legacy';
297
406
 
298
407
  // GitHub open PRs
299
- <ScorecardHomepageCard metricId="github.open_prs" />
408
+ <ScorecardHomepageCard metricId="github.openPRs" />
300
409
 
301
410
  // Jira open issues
302
- <ScorecardHomepageCard metricId="jira.open_issues" />
411
+ <ScorecardHomepageCard metricId="jira.openIssues" />
303
412
  ```
304
413
 
305
414
  4. Ensure the frontend can reach the Scorecard backend by configuring discovery in `app-config.yaml` (see discovery snippet under [NFS](#nfs-new-frontend-system--app)).
@@ -337,15 +446,15 @@ permission:
337
446
 
338
447
  ### Homepage scorecard cards
339
448
 
340
- The plugin exports **`ScorecardHomepageCard`** (see [`plugin.ts`](./src/plugin.ts)) for use on customizable home pages (for example **Dynamic Home Page** mount points such as `home.page/cards`).
449
+ The plugin exports **`ScorecardHomepageCard`** from `@red-hat-developer-hub/backstage-plugin-scorecard/legacy` (see [`plugin.ts`](./src/plugin.ts)) for use on customizable home pages (for example **Dynamic Home Page** mount points such as `home.page/cards`).
341
450
 
342
451
  #### Backend configuration
343
452
 
344
453
  Define KPI ids and optional labels under **`scorecard.aggregationKPIs`** so each card can call **`GET /aggregations/<aggregationId>`** with a stable id. See [Scorecard backend README — Aggregation KPIs](../scorecard-backend/README.md#aggregation-kpis-homepage-and-get-aggregations). If you omit a KPI entry, use the **metric id** as `aggregationId` (default status-grouped aggregation).
345
454
 
346
- **`type: average`** KPIs require **`options.statusScores`** (weights per threshold rule key). Optionally set **`options.thresholds`** so the API returns **`aggregationChartDisplayColor`** for the headline percentage. Behavior, validation, and drill-down notes are described in [aggregation.md](../scorecard-backend/docs/aggregation.md).
455
+ **`type: weightedStatusScore`** KPIs require **`options.statusScores`** (weights per threshold rule key). Optionally set **`options.thresholds`** so the API returns **`aggregationChartDisplayColor`** for the headline percentage. Behavior, validation, and drill-down notes are described in [aggregation.md](../scorecard-backend/docs/aggregation.md).
347
456
 
348
- For **`type: average`**, the homepage card shows a **centered donut** with the headline percentage. Hovering the **center** opens a tooltip with **total score**, **max possible score**, and a **per-status breakdown** (from aggregation **`result.values`**). There is **no side status legend**; **`statusGrouped`** cards use a multi-slice pie with a legend instead.
457
+ For **`type: weightedStatusScore`**, the homepage card shows a **centered donut** with the headline percentage. Hovering the **center** opens a tooltip with **total score**, **max possible score**, and a **per-status breakdown** (from aggregation **`result.values`**). There is **no side status legend**; **`statusGrouped`** cards use a multi-slice pie with a legend instead.
349
458
 
350
459
  #### Card props
351
460
 
@@ -368,7 +477,7 @@ The supported model is **a single `aggregationId` string** whose value is either
368
477
  Example (Dynamic Home Page–style mount point): register **`ScorecardHomepageCard`** and pass **`props.aggregationId`** (and **`metricId`** only if you still run an older card API):
369
478
 
370
479
  ```tsx
371
- import { ScorecardHomepageCard } from '@red-hat-developer-hub/backstage-plugin-scorecard';
480
+ import { ScorecardHomepageCard } from '@red-hat-developer-hub/backstage-plugin-scorecard/legacy';
372
481
  import { ComponentType } from 'react';
373
482
 
374
483
  // Inside your home page cards config:
@@ -380,7 +489,7 @@ import { ComponentType } from 'react';
380
489
  layouts: { /* … */ },
381
490
  props: {
382
491
  aggregationId: 'openIssuesKpi',
383
- // metricId: 'jira.open_issues', // legacy only; remove when only aggregationId is supported
492
+ // metricId: 'jira.openIssues', // legacy only; remove when only aggregationId is supported
384
493
  },
385
494
  },
386
495
  },
@@ -448,7 +557,7 @@ If a translation key is not found, the plugin will automatically fall back to:
448
557
  ```typescript
449
558
  // In ref.ts
450
559
  metric: {
451
- 'github.open_prs': {
560
+ 'github.openPRs': {
452
561
  title: 'GitHub open PRs',
453
562
  description: 'Current count of open Pull Requests for a given GitHub repository',
454
563
  },
package/dist/alpha.d.ts CHANGED
@@ -1,88 +1,124 @@
1
- import * as react from 'react';
2
1
  import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
3
- import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
4
- export { s as scorecardTranslationRef, a as scorecardTranslations } from './types/index.d-DLQMegMp.js';
5
2
 
6
3
  /**
7
- * The primary Scorecard frontend plugin.
8
- * @alpha
4
+ * Translation reference for scorecard plugin
5
+ * @public
9
6
  */
10
- declare const _default: _backstage_frontend_plugin_api.OverridableFrontendPlugin<{
11
- root: _backstage_core_plugin_api.RouteRef<undefined>;
12
- drillDown: _backstage_core_plugin_api.RouteRef<{
13
- aggregationId: string;
14
- metricId: string;
15
- }>;
16
- }, {}, {
17
- "api:scorecard": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
18
- kind: "api";
19
- name: undefined;
20
- config: {};
21
- configInput: {};
22
- output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
23
- inputs: {};
24
- params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
25
- }>;
26
- "page:scorecard": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
27
- kind: "page";
28
- name: undefined;
29
- config: {
30
- path: string | undefined;
31
- title: string | undefined;
32
- };
33
- configInput: {
34
- path?: string | undefined;
35
- title?: string | undefined;
36
- };
37
- output: _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
38
- optional: true;
39
- }> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.title", {
40
- optional: true;
41
- }> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.IconElement, "core.icon", {
42
- optional: true;
43
- }>;
44
- inputs: {
45
- pages: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
46
- optional: true;
47
- }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "core.title", {
48
- optional: true;
49
- }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.IconElement, "core.icon", {
50
- optional: true;
51
- }>, {
52
- singleton: false;
53
- optional: false;
54
- internal: false;
55
- }>;
56
- };
57
- params: {
58
- path: string;
59
- title?: string;
60
- icon?: _backstage_frontend_plugin_api.IconElement;
61
- loader?: () => Promise<react.JSX.Element>;
62
- routeRef?: _backstage_frontend_plugin_api.RouteRef;
63
- noHeader?: boolean;
64
- };
65
- }>;
7
+ declare const scorecardTranslationRef: _backstage_frontend_plugin_api.TranslationRef<"plugin.scorecard", {
8
+ readonly "emptyState.title": string;
9
+ readonly "emptyState.description": string;
10
+ readonly "emptyState.button": string;
11
+ readonly "emptyState.altText": string;
12
+ readonly "notFound.title": string;
13
+ readonly "notFound.description": string;
14
+ readonly "notFound.altText": string;
15
+ readonly "notFound.readMore": string;
16
+ readonly "notFound.goBack": string;
17
+ readonly "notFound.contactSupport": string;
18
+ readonly "permissionRequired.title": string;
19
+ readonly "permissionRequired.description": string;
20
+ readonly "permissionRequired.button": string;
21
+ readonly "permissionRequired.altText": string;
22
+ readonly "common.loading": string;
23
+ readonly "errors.entityMissingProperties": string;
24
+ readonly "errors.missingAggregationId": string;
25
+ readonly "errors.invalidApiResponse": string;
26
+ readonly "errors.fetchError": string;
27
+ readonly "errors.metricDataUnavailable": string;
28
+ readonly "errors.invalidThresholds": string;
29
+ readonly "errors.missingPermission": string;
30
+ readonly "errors.noDataFound": string;
31
+ readonly "errors.authenticationError": string;
32
+ readonly "errors.missingPermissionMessage": string;
33
+ readonly "errors.userNotFoundInCatalogMessage": string;
34
+ readonly "errors.noDataFoundMessage": string;
35
+ readonly "errors.unsupportedAggregationType": string;
36
+ readonly "errors.authenticationErrorMessage": string;
37
+ readonly "metric.github.openPRs.title": string;
38
+ readonly "metric.github.openPRs.description": string;
39
+ readonly "metric.jira.openIssues.title": string;
40
+ readonly "metric.jira.openIssues.description": string;
41
+ readonly "metric.sonarqube.qualityGate.title": string;
42
+ readonly "metric.sonarqube.qualityGate.description": string;
43
+ readonly "metric.sonarqube.openIssues.title": string;
44
+ readonly "metric.sonarqube.openIssues.description": string;
45
+ readonly "metric.sonarqube.securityRating.title": string;
46
+ readonly "metric.sonarqube.securityRating.description": string;
47
+ readonly "metric.sonarqube.securityIssues.title": string;
48
+ readonly "metric.sonarqube.securityIssues.description": string;
49
+ readonly "metric.sonarqube.securityReviewRating.title": string;
50
+ readonly "metric.sonarqube.securityReviewRating.description": string;
51
+ readonly "metric.sonarqube.securityHotspots.title": string;
52
+ readonly "metric.sonarqube.securityHotspots.description": string;
53
+ readonly "metric.sonarqube.reliabilityRating.title": string;
54
+ readonly "metric.sonarqube.reliabilityRating.description": string;
55
+ readonly "metric.sonarqube.reliabilityIssues.title": string;
56
+ readonly "metric.sonarqube.reliabilityIssues.description": string;
57
+ readonly "metric.sonarqube.maintainabilityRating.title": string;
58
+ readonly "metric.sonarqube.maintainabilityRating.description": string;
59
+ readonly "metric.sonarqube.maintainabilityIssues.title": string;
60
+ readonly "metric.sonarqube.maintainabilityIssues.description": string;
61
+ readonly "metric.sonarqube.codeCoverage.title": string;
62
+ readonly "metric.sonarqube.codeCoverage.description": string;
63
+ readonly "metric.sonarqube.codeDuplications.title": string;
64
+ readonly "metric.sonarqube.codeDuplications.description": string;
65
+ readonly "metric.filecheck.title": string;
66
+ readonly "metric.filecheck.description": string;
67
+ readonly "metric.lastUpdated": string;
68
+ readonly "metric.lastUpdatedNotAvailable": string;
69
+ readonly "metric.someEntitiesNotReportingValues": string;
70
+ readonly "metric.weightedStatusScoreCenterTooltipTotalLabel": string;
71
+ readonly "metric.weightedStatusScoreCenterTooltipMaxLabel": string;
72
+ readonly "metric.weightedStatusScoreCenterTooltipBreakdownRow_one": string;
73
+ readonly "metric.weightedStatusScoreCenterTooltipBreakdownRow_other": string;
74
+ readonly "metric.weightedStatusScoreLegendTooltipEntitiesEach_one": string;
75
+ readonly "metric.weightedStatusScoreLegendTooltipEntitiesEach_other": string;
76
+ readonly "metric.weightedStatusScoreLegendTooltipRowTotal": string;
77
+ readonly "metric.drillDownCalculationFailures": string;
78
+ readonly "metric.homepageEntityHealthRatio": string;
79
+ readonly "metric.homepageEntityCalculationHealth": string;
80
+ readonly "thresholds.success": string;
81
+ readonly "thresholds.warning": string;
82
+ readonly "thresholds.error": string;
83
+ readonly "thresholds.exist": string;
84
+ readonly "thresholds.missing": string;
85
+ readonly "thresholds.noEntities": string;
86
+ readonly "thresholds.entities_one": string;
87
+ readonly "thresholds.entities_other": string;
88
+ readonly "dataSourcesDialog.title": string;
89
+ readonly "dataSourcesDialog.close": string;
90
+ readonly "dataSourcesDialog.unknownPlugin": string;
91
+ readonly "dataSourcesDialog.statusTooltip": string;
92
+ readonly "dataSourcesDialog.columns.plugin": string;
93
+ readonly "dataSourcesDialog.columns.check": string;
94
+ readonly "dataSourcesDialog.columns.value": string;
95
+ readonly "dataSourcesDialog.columns.status": string;
96
+ readonly "dataSourcesDialog.columns.lastSynced": string;
97
+ readonly "metricGroupCard.menuAriaLabel": string;
98
+ readonly "metricGroupCard.viewDataSources": string;
99
+ readonly "entitiesPage.missingPermission": string;
100
+ readonly "entitiesPage.noDataFound": string;
101
+ readonly "entitiesPage.unknownMetric": string;
102
+ readonly "entitiesPage.metricProviderNotRegistered": string;
103
+ readonly "entitiesPage.entitiesTable.title": string;
104
+ readonly "entitiesPage.entitiesTable.unavailable": string;
105
+ readonly "entitiesPage.entitiesTable.titleWithCount": string;
106
+ readonly "entitiesPage.entitiesTable.header.lastUpdated": string;
107
+ readonly "entitiesPage.entitiesTable.header.value": string;
108
+ readonly "entitiesPage.entitiesTable.header.status": string;
109
+ readonly "entitiesPage.entitiesTable.header.entity": string;
110
+ readonly "entitiesPage.entitiesTable.header.owner": string;
111
+ readonly "entitiesPage.entitiesTable.header.kind": string;
112
+ readonly "entitiesPage.entitiesTable.footer.of": string;
113
+ readonly "entitiesPage.entitiesTable.footer.allRows": string;
114
+ readonly "entitiesPage.entitiesTable.footer.rows_one": string;
115
+ readonly "entitiesPage.entitiesTable.footer.rows_other": string;
66
116
  }>;
67
117
 
68
118
  /**
69
- * Catalog module that injects the Scorecard tab and into Catalog entity pages.
70
- *
71
- * Also ships grid and list layout extensions (disabled by default).
72
- * Enable them in app-config.yaml to get a layout toggle in the entity tab.
73
- *
74
- * @alpha
119
+ * Translation Resource for scorecard
120
+ * @public
75
121
  */
76
- declare const scorecardCatalogModule: _backstage_frontend_plugin_api.FrontendModule;
77
- /**
78
- * App module that automatically registers Scorecard translations.
79
- * @alpha
80
- */
81
- declare const scorecardTranslationsModule: _backstage_frontend_plugin_api.FrontendModule;
82
- /**
83
- * Home module that contributes scorecard homepage widget and layout.
84
- * @alpha
85
- */
86
- declare const scorecardHomeModule: _backstage_frontend_plugin_api.FrontendModule;
122
+ declare const scorecardTranslations: _backstage_frontend_plugin_api.TranslationResource<"plugin.scorecard">;
87
123
 
88
- export { _default as default, scorecardCatalogModule, scorecardHomeModule, scorecardTranslationsModule };
124
+ export { scorecardTranslationRef, scorecardTranslations };
package/dist/alpha.esm.js CHANGED
@@ -1,51 +1,3 @@
1
- import { createFrontendPlugin, createFrontendModule } from '@backstage/frontend-plugin-api';
2
- import { TranslationBlueprint } from '@backstage/plugin-app-react';
3
- import { scorecardDrillDownRouteRef, rootRouteRef } from './routes.esm.js';
4
- import { scorecardTranslations } from './translations/index.esm.js';
5
- import { scorecardApi } from './alpha/extensions/api.esm.js';
6
- import { scorecardEntityContent } from './alpha/extensions/entityTab.esm.js';
7
- import { aggregatedCardWithDeprecatedMetricIdWidget, aggregatedCardWithDefaultAggregationWidget, aggregatedCardWithJiraOpenIssuesWidget, aggregatedCardWithGithubOpenPrsWidget, aggregatedCardWithGithubFilecheckLicenseWidget, aggregatedCardWithGithubFilecheckCodeownersWidget, aggregatedCardWithGithubOpenPrsWeightedWidget } from './alpha/extensions/homePageCards.esm.js';
8
- import { scorecardPage } from './alpha/extensions/scorecardPage.esm.js';
9
- import { scorecardEntityLayoutGrid, scorecardEntityLayoutList } from './alpha/extensions/scorecardLayoutExtensions.esm.js';
1
+ export { scorecardTranslations } from './translations/index.esm.js';
10
2
  export { scorecardTranslationRef } from './translations/ref.esm.js';
11
-
12
- const scorecardTranslation = TranslationBlueprint.make({
13
- params: {
14
- resource: scorecardTranslations
15
- }
16
- });
17
- var index = createFrontendPlugin({
18
- pluginId: "scorecard",
19
- extensions: [scorecardApi, scorecardPage],
20
- routes: {
21
- root: rootRouteRef,
22
- drillDown: scorecardDrillDownRouteRef
23
- }
24
- });
25
- const scorecardCatalogModule = createFrontendModule({
26
- pluginId: "catalog",
27
- extensions: [
28
- scorecardEntityContent,
29
- scorecardEntityLayoutGrid,
30
- scorecardEntityLayoutList
31
- ]
32
- });
33
- const scorecardTranslationsModule = createFrontendModule({
34
- pluginId: "app",
35
- extensions: [scorecardTranslation]
36
- });
37
- const scorecardHomeModule = createFrontendModule({
38
- pluginId: "home",
39
- extensions: [
40
- aggregatedCardWithDeprecatedMetricIdWidget,
41
- aggregatedCardWithDefaultAggregationWidget,
42
- aggregatedCardWithJiraOpenIssuesWidget,
43
- aggregatedCardWithGithubOpenPrsWidget,
44
- aggregatedCardWithGithubFilecheckLicenseWidget,
45
- aggregatedCardWithGithubFilecheckCodeownersWidget,
46
- aggregatedCardWithGithubOpenPrsWeightedWidget
47
- ]
48
- });
49
-
50
- export { index as default, scorecardCatalogModule, scorecardHomeModule, scorecardTranslations, scorecardTranslationsModule };
51
3
  //# sourceMappingURL=alpha.esm.js.map