feat(scorecard): add homepage sparkline charts for time-series metrics - #4596
Eswaraiahsapram wants to merge 8 commits into
Conversation
|
Important This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior. Missing ChangesetsThe following package(s) are changed by this PR but do not have a changeset:
See CONTRIBUTING.md for more information about how to add changesets. Changed Packages
|
|
🤖 Finished Review · ✅ Success · Started 9:04 AM UTC · Completed 9:11 AM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Cost: $1.99 |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #4596 +/- ##
==========================================
+ Coverage 63.60% 63.64% +0.03%
==========================================
Files 2685 2688 +3
Lines 107077 107214 +137
Branches 30010 30070 +60
==========================================
+ Hits 68101 68231 +130
- Misses 37165 37172 +7
Partials 1811 1811
*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:
|
Review — ApprovePR: #4596 — Feat/scorecard homepage sparkline cards UI SummaryThis PR adds sparkline chart support to the scorecard plugin, enabling time-series visualization for DORA metrics on both entity pages and the homepage. The implementation is well-structured with clean separation across API client methods, React hooks, reusable chart components, and shared utility functions. Key additions:
FindingsNo critical, high, or medium-severity issues found. Low-severity observations
AssessmentThe code quality is high throughout. Specific strengths:
Note: This PR declares a dependency on PR #4573 and has the |
2d8ea7d to
fb15906
Compare
dzemanov
left a comment
There was a problem hiding this comment.
Thank you for the PR.
Looks good, just a couple of quick comments:
| - `AggregatedCardWithTotalOpenBugs` (title: **Scorecard: Total open bugs**) | ||
| - `AggregatedCardWithEntitiesWithOpenPrs` (title: **Scorecard: Entities with open PRs**) | ||
| - `AggregatedCardWithAvgOpenPrs` (title: **Scorecard: Average open PRs**) | ||
| - `AggregatedCardWithAvgDeploymentFrequency` (title: **Scorecard: Average deployment frequency**) |
There was a problem hiding this comment.
When you will add the last DORA metric for MedianTimeToRestore, please update also docs, thank you!
| components: lazyScorecardWidget( | ||
| ScorecardHomepageCardWithProvider => () => | ||
| ( | ||
| <ScorecardHomepageCardWithProvider aggregationId="avgChangeFailureRate" /> |
There was a problem hiding this comment.
When testing with default configuration, I get:
Screen.Recording.2026-09-17.at.11.23.11.mov
All avg dora widgets except for deployment frequency are always loading.
This is because default app-config configuration is missing all avg dora configurations except for avgDeploymentFrequency: https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/scorecard/app-config.yaml#L373
I am not familiar much with NFS blueprints in RHDH. If we are providing only these blueprint widgets, this means that in NFS for example for filecheck, users are unable to create aggregation cards except for checking for codeowners and license file because that is the only configuration we provide here and here in blueprints?
This also means if they forget to add that key to their app-config configuration, that they are always in load state?
It would be good to fix that if metadata API returns not found, widgets are not in always loading state.
Going back to dora, maybe it makes sense to provide at least 1 dora metric with Deprecated metric id (at least for legacy - so we can easier test it is working) - so for example dora.changeFailureRate. We can keep avgDeploymentFrequency as we already have it in app-config. But maybe we really want to provide all 4 dora metrics also in blueprints with deprecated metric id, as otherwise users will need to have them configured in their app-config?
For aggregationId, I am thinking we might want to make the ids general? So instead of avgChangeFailureRate we have 'changeFailureRateKpi' similiar to openIssuesKpi? Just because you can specify different type: sum etc in your scorecard configuration (avg is default), what do you think? Using custom aggregationId instead of deprecated metric id means you will need to add all those configurations to default app config.
There was a problem hiding this comment.
Thanks @dzemanov.
-
Default configurations: I'll add the missing KPI config to the default app-config.
-
NFS blueprints: The available homepage cards depend on the blueprints we provide. Users cannot create new widget with custom aggregation IDs unless we/they provide a blueprint widget. Custom KPI IDs also require matching app-config entries
-
I'll add at least one DORA widget using deprecated metricId to test
-
Aggregation ID naming: I agree that avgChangeFailureRate is not a good name because the aggregation type can be changed. I'll use names like changeFailureRateKpi and deploymentFrequencyKpi, following the existing openIssuesKpi pattern.
c0284dd to
fbbff9d
Compare
fbbff9d to
8a7bac9
Compare
dzemanov
left a comment
There was a problem hiding this comment.
Retested,
default configuration works as expected.
No configuration of aggregation kpi is no longer loading infinitely:
It doesn't look nice, but is in line with how other errors are shown, thanks for the update.
I don't know if this is as a result of fixing loading, but first time when I add scorecard, I get auth error. When I reload, everything works.
Screen.Recording.2026-09-17.at.22.04.47.mov
No data works fine:
Single points:
Drill down with single points:
2 points:
Different values:
Screen.Recording.2026-09-17.at.21.30.26.mov
Translation:
Screen.Recording.2026-09-17.at.21.37.03.mov
Just wanted to mention, title and description translations are currently unused for
dora aggregation KPIs in NFS blueprints (and also all other KPIs that don't use as aggregation id metric id), as the app-config always overrides
them (this is expected behavior as user configured those). For a future release, we could explore removing the need for the app-config configuration by adding blueprints that use aggregationId=metricId and using as aggregation thresholds by default metric-defined thresholds instead of DEFAULT_NUMBER_THRESHOLDS.
Would be good to truncate the values for graphs:
@Eswaraiahsapram, adding current value is to be done within a different ticket?
Design:
View datasources settings are missing as well for home page, can be added in a different PR as well.
| const matchingThresholdKey = chartColorToken | ||
| ? thresholdRules?.find( | ||
| rule => | ||
| getThresholdRuleColor(thresholdRules, rule.key) === chartColorToken, |
There was a problem hiding this comment.
Yeah, this reverse engineering of matched threshold by color to get stroke is not great. But backend doesn't provide it so thank you for getting around this. We can fix that in future if needed.
dzemanov
left a comment
There was a problem hiding this comment.
Permissions work fine:
Screen.Recording.2026-09-17.at.22.10.02.mov
70c4be9 to
2d6f7e8
Compare
|
|
Thanks a lot @dzemanov for the feedback.
Thanks. We have a jira bug for similar issue - https://redhat.atlassian.net/browse/RHDHBUGS-3263
I haven't been able to reproduce this locally. Could you please share the steps? If it still reproduces, I’m happy to file a follow-up bug. Screen.Recording.2026-09-18.at.10.23.26.AM.mov
Fixed - graph values are truncated to 4 decimal places.
Thanks for flagging this. I’ve added the
Agreed, we'll pick this up in a follow-up PR. |



Hey, I just made a Pull Request!
Follows #4573 (merged). Reuses the shared sparkline chart, legend, and time-series utilities from that PR on the Scorecard homepage.
What
Adds sparkline visualization on Scorecard homepage cards when aggregation metadata
visualizationissparkline(for example DORA). Each card shows a 30-day trend and a threshold legend. Legend and line color come from the time-series threshold rules.Screenshots
Screen.Recording.2026-09-17.at.1.49.33.PM.mov
What changed
Homepage rendering
ScorecardHomepageCardloadsGET /aggregations/:aggregationId/metadatafirst. Whenmetadata.visualizationissparkline, it fetches the aggregation time series instead of the snapshot and rendersAggregatedSparklineCard. Other aggregations keep the existing pie, donut, and scalar cards.AggregatedSparklineCard— homepage sparkline card using the sharedSparklineChart/toSparklineChartModelpath from feat(scorecard): add entity-page sparkline charts for time-series metrics #4573, including entity subheader (success count / total) and last-synced info.New API hook
useAggregationTimeSeries—useQueryhook for the default 30-day aggregation time series (GET /aggregations/:aggregationId/time-series).Homepage widgets
Registers NFS and legacy homepage widgets for:
avgDeploymentFrequency)avgChangeFailureRate)avgMedianLeadTimeForChanges)Docs
AggregatedSparklineCardpath for sparkline aggregations.How to test
visualizationissparkline) and add a homepage Scorecard card withaggregationIdsuch asavgDeploymentFrequency.✔️ Checklist