feat(scorecard): add entity-page sparkline charts for time-series metrics - #4573
Conversation
|
Important This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior. Changed Packages
|
|
🤖 Finished Review · ✅ Success · Started 7:36 PM UTC · Completed 7:44 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Cost: $2.16 |
Review — ApproveScope: Adds sparkline (area chart) visualization for entity-page scorecard metrics whose This is a well-structured, cleanly decomposed feature PR. The code follows existing project patterns, has thorough input validation and error handling, and ships with excellent test coverage across all new and modified modules. Correctness
SecurityNo concerns. No authentication or authorization changes. All new API calls use the existing Intent & CoherenceThe change matches its stated purpose and is appropriately scoped as a foundation PR. Shared chart components and utilities are designed for reuse by the homepage sparkline PR that follows. The changeset correctly selects a Style & Conventions
DocumentationThe PR body is thorough with component descriptions, API endpoints, test instructions, and a checklist. In-code documentation (JSDoc, type comments) is present on all public-facing utilities. The checklist items for changeset, docs, tests, and screenshots are tracked but some are unchecked — the author should verify these before merge. Observations
No medium or higher severity findings. The PR is safe to merge. Previous runReviewFindingsMedium
Low
Labels: Feature PR adding new sparkline chart capability to the scorecard workspace. Previous run (2)ReviewVerdict: comment This PR adds sparkline (area chart) visualization support for entity-page scorecard metrics, including new chart components, API methods, hooks, utilities, and i18n strings. The architecture is well-structured: components follow the existing project patterns, hooks use the established Two medium-severity findings require attention before merge. Several low-severity items are noted for consideration. Medium1. Stale API report —
|
b56fa91 to
3dd8c8b
Compare
|
🤖 Review · ❌ Terminated · Started 8:53 AM UTC · Ended 9:09 AM UTC Commit: |
|
🤖 Finished Review · ✅ Success · Started 8:53 AM UTC · Completed 9:09 AM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Cost: $9.51 |
|
🤖 Finished Review · ✅ Success · Started 9:11 AM UTC · Completed 9:53 AM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Cost: $13.56 |
46c6489 to
159c8f3
Compare
|
🤖 Review · ❌ Terminated · Started 6:12 AM UTC · Ended 6:39 AM UTC Commit: |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #4573 +/- ##
==========================================
+ Coverage 62.58% 62.70% +0.11%
==========================================
Files 2634 2649 +15
Lines 105187 105619 +432
Branches 29506 29627 +121
==========================================
+ Hits 65833 66228 +395
- Misses 37535 37577 +42
+ Partials 1819 1814 -5
*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:
|
|
🤖 Finished Review · ✅ Success · Started 6:12 AM UTC · Completed 6:39 AM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Cost: $1.78 |
There was a problem hiding this comment.
Thank you for the PR!
Tested for data with both successes and errors (both at the start / end or in the middle):
Screen.Recording.2026-09-08.at.12.44.36.mov
I am not sure if I have misconfigured something, but I see only the resulting threshold in legend.
I see we are not providing thresholds in time-series response, we might need to update that. Meanwhile you can skip fixing it or you can take if from metric result.
When I have only 1 data point:
What could help:
The frontend should display data points for all 30 days, even if data is missing, indicating absence with "No data recorded for this date."
Only 2 data points:
Translation:
Collector description might need to also be provided:
For development, I tried running:
yarn start in the plugins folder, but I did not see new sparkline cards:
This is not blocking, but worth fixing / adding different cases for future to avoid seeding database for some of the testing.
Group cards work nice:
Screen.Recording.2026-09-08.at.13.00.15.mov
There is . missing in median lead time for changes description, I will update it.
@ShiranHi, is View datasources description alright in this state?
This is description for group card:
For individual dora cards, 'View datasources' shows:
For individual "View Datasources" DORA cards, should we also include both the metric description and the collector description? It would make the metrics easier to understand, but it would mean repeating the same information on each row.
Incorporating the metric name and description directly into the collector description is not possible due to the collector's use across multiple metrics.
Current descriptions:
github:deployments: Collects GitHub deployments.
github:deploymentWorkflowRuns: Collects deployments from GitHub Actions.
github:deploymentPullRequests: Collects pull requests linked to deployments.
jira:incidents Collects Jira incidents.
ciiay
left a comment
There was a problem hiding this comment.
Thanks for the PR — the shared chart stack, DataSourcesDialog refactor, and test coverage are in good shape. I agree with @dzemanov's manual testing feedback and am also requesting changes before merge.
Blocking
-
Sparse / missing days in the 30-day window — The chart only plots API-returned points. With 1–2 data points the sparkline is misleading (flat line, no meaningful x-axis). Please fill the requested 30-day range on the frontend and mark missing days in the tooltip (e.g. "No data recorded for this date") rather than reusing
errors.metricDataUnavailable. -
Threshold legend —
EntitySparklineCardcurrently passes only the matched rule (legendRules: matchedRule ? [matchedRule] : undefined), so users see a single band. Since the time-series response does not include thresholds yet, please derive the full legend frommetric.result.thresholdResult.definition.ruleswhile keeping line color/style tied to the current evaluation. -
Single-point UX — When there is only one tick,
SparklineCharthides x-axis labels (xTicks.length <= 1). Please show at least one date label or an explicit insufficient-history state. -
i18n —
dataSourcesDialog.collectorStatusTooltiphardcodes "DORA" in all locales but applies to any collector-backed metric. Please generalize (interpolation or neutral wording). A native-speaker pass on the new German strings would also help.
Should address (non-blocking but recommended)
- SonarCloud — Quality gate fails on ~3.9% duplication in new code; likely duplicated mock time-series code in
dev/mocks.tsanddev/legacy.tsx— extract a shared fixture. useMetricCollectors— Align error handling withuseMetricTimeSeries(translated fetch errors inqueryFn).- API response validation — Consider validating
points[]entry shape, not just top-level object checks (see inline threads). getAggregationTimeSeries— Fine to land here for the homepage follow-up PR, but worth a brief note in the PR description since it has no caller yet.- Data sources dialog content — Open question from @dzemanov on whether individual DORA cards should include metric description alongside collector description; needs product sign-off.
Happy to re-review once the sparse-data and legend items are addressed.
|
Thanks a lot @dzemanov , for reviewing this 🙏
@dzemanov , this is intentional for the entity page. As per prototype, the legend shows only the matched / current threshold (e.g. Medium), and the line color/style follow that evaluation. For homepage aggregation cards we will show all threshold bands in the legend. That is in the homepage follow-up PR.
Thanks @dzemanov, we can check with UX before changing it. @ShiranHi, Right now, with a single sample we plot that point as-is (dot, no filled 30-day line). That matches the prototype Filling all 30 days and showing “No data recorded for this date.” on the gaps would make the trend easier to read, but it is also a different look from the prototype (lots of empty/missing days vs one point). @ShiranHi, which should we follow for the entity sparkline?
|
159c8f3 to
2d6f8e3
Compare
|
🤖 Review · ❌ Terminated · Started 9:28 AM UTC · Ended 9:30 AM UTC Commit: |
|
🤖 Finished Review · ❌ Failure (validation failed after 2 iteration(s)) · Started 9:28 AM UTC · Completed 9:30 AM UTC Commit: Runtime: claude · Model: opus → claude-opus-5 |
|
🤖 Review · ❌ Terminated · Started 9:37 AM UTC · Ended 9:39 AM UTC Commit: |
|
🤖 Finished Review · ❌ Failure (validation failed after 2 iteration(s)) · Started 9:37 AM UTC · Completed 9:39 AM UTC Commit: Runtime: claude · Model: opus → claude-opus-5 |
There are two topics here:
|
c1a7888 to
2dec824
Compare
|
🤖 Review · ❌ Terminated · Started 12:01 PM UTC · Ended 12:23 PM UTC Commit: |
|
|
🤖 Finished Review · ❌ Failure (agent timed out after 20m0s without completing (timeout: 20m0s)) · Started 12:01 PM UTC · Completed 12:23 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 |




Hey, I just made a Pull Request!
Fix - https://redhat.atlassian.net/browse/RHIDP-15576
What
Adds sparkline (area chart) visualization support for entity-page scorecard metrics whose
defaultVisualizationissparkline. This is the foundation PR — shared chart components and utilities are included here and will be reused by the homepage sparkline PR that follows.What changed
New components
SparklineChart— Recharts-based area chart with gradient fill, error-dot markers, hover tooltip, and threshold legendSparklineTooltip/SparklineLegend— supporting chart sub-componentsEntitySparklineCard— entity-page card that fetches time-series data and renders a sparkline with a "View data sources" dialog for collector metadataEntityMetricCard— routing component that rendersEntitySparklineCardor the existingScorecardcard based ondefaultVisualizationNew API methods
getMetricTimeSeries—GET /metrics/catalog/:kind/:namespace/:name/time-seriesgetMetricCollectors—GET /metrics/:metricId/collectorsNew hooks
useMetricTimeSeries—useQuery-based hook for 30-day entity metric time seriesuseMetricCollectors—useQuery-based hook for collector metadata (fetched only when the data-sources dialog is open)New utilities
timeSeriesChartData— maps API points to chart-ready data with interpolation for error gapssparklineLegend— builds threshold legend items with color + line-style pairingsparklineChartModel— shared view-model factory used by both entity and homepage cardsmetricVisualization—isSparklineVisualization()helpertimeSeriesRange— computes the default 30-day ISO-8601 rangeRefactors
DataSourcesDialognow accepts genericSourceRow[]instead of building rows internallycollectorSourceRows.ts(for sparkline metrics) andmetricSourceRows.ts(for existing donut metrics) as separate row buildersGitHub,Jira, empty value--, unavailable statusN/A) are now translated via i18n keys instead of hardcoded stringsTranslations
dataSourcesDialog.*keys toref.tsand all locale files (de, es, fr, it, ja)Screen Recording
Screen.Recording.2026-09-07.at.3.18.23.PM.mov
How to test
defaultVisualization: sparkline)✔️ Checklist