feat: show icons when threhsolds are reached, remove threhsold lines#123
Conversation
✅ Deploy Preview for agentscan ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
📝 WalkthroughWalkthroughAccountEventsTimeline.vue refactors threshold visualization from built-in chart annotations to custom SVG alert icons. The component now enriches dataset items with threshold values, computes alert icon coordinates by comparing data against thresholds, removes annotation-based scale logic, adjusts layout and scale to accommodate icons, and renders icons through an SVG slot. ChangesThreshold rendering refactor: annotations to SVG alert icons
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
app/components/Chart/AccountEventsTimeline.vue (1)
260-291: ⚡ Quick win
Datapoints.thresholdshould reflect that the field can be null/undefined.
config.thresholdisnullforCreateEvent(Line 78), so the data items written on Line 144 carrythreshold: number | null. Declaringthreshold: numberhere means the runtime filter on Line 274 (d.threshold !== null && d.threshold !== undefined) looks redundant to TypeScript, and the>= d.thresholdcomparison on Line 286 silently relies on the (incorrect)numbertype rather than narrowing through the filter. Tightening the type and using a type predicate makes the null-handling intent explicit and keeps TS honest:♻️ Proposed type refinement
-type Datapoints = Array<VueUiXyDatasetLineItem & { threshold: number }>; +type Datapoint = VueUiXyDatasetLineItem & { threshold: number | null | undefined }; +type Datapoints = Array<Datapoint>; @@ -function alertIcons(data: Datapoints, zoomOffset = 0): PlotAlert[] { - return data - .filter((d) => d.threshold !== null && d.threshold !== undefined) - .map((d) => { +function alertIcons(data: Datapoints, zoomOffset = 0): PlotAlert[] { + return data + .filter((d): d is Datapoint & { threshold: number } => + d.threshold !== null && d.threshold !== undefined, + ) + .map((d) => {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/components/Chart/AccountEventsTimeline.vue` around lines 260 - 291, Update the Datapoints type so threshold can be null/undefined (e.g., threshold: number | null | undefined) and change the filter in alertIcons to a type predicate that narrows d to the non-null-threshold case before mapping; this ensures TypeScript knows d.threshold is a number when used in the isAlert comparison inside alertIcons (refer to Datapoints, PlotAlert, and the alertIcons function and its filter/map logic).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/components/Chart/AccountEventsTimeline.vue`:
- Around line 206-208: The current top chart padding in
AccountEventsTimeline.vue (padding.top = 24) is too small for the lightning-bolt
alert icon drawn by the path using plot.x/plot.y (see the path at line with "M
${plot.x - 4} ${plot.y - 6} l 12 -17 ..." which extends ~36px above the
datapoint); increase padding.top to ~36–40 (or reduce the icon's vertical extent
in the lightning-bolt path) so the icon has sufficient headroom and won't be
clipped or overlap chart chrome—update the padding.top value or adjust the path
coordinates accordingly in the component.
- Around line 173-179: The computed maxValue currently calls
Math.max(...datasetLine.value.filter(s =>
selectedLegendItems.value.includes(s.name)).flatMap(d => d.series.map(v => v ??
0))) which can produce -Infinity when the filtered array is empty; update the
maxValue computed (referencing datasetLine and selectedLegendItems) to first
build the flattened values array, check if it is empty, and return a safe
fallback (e.g., 0) in that case, or alternatively call Math.max with a fallback
like Math.max(0, ...values) so scaleMax (the value used later to set the y-axis)
never receives -Infinity.
---
Nitpick comments:
In `@app/components/Chart/AccountEventsTimeline.vue`:
- Around line 260-291: Update the Datapoints type so threshold can be
null/undefined (e.g., threshold: number | null | undefined) and change the
filter in alertIcons to a type predicate that narrows d to the
non-null-threshold case before mapping; this ensures TypeScript knows
d.threshold is a number when used in the isAlert comparison inside alertIcons
(refer to Datapoints, PlotAlert, and the alertIcons function and its filter/map
logic).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 303f7e52-3a17-430e-8c52-c72e777ff266
📒 Files selected for processing (1)
app/components/Chart/AccountEventsTimeline.vue

This removes the threshold lines from the account timeline chart, and displays icons above datapoints that actually exceed the threshold:
Icons will be displayed above exceeding datapoints for the forks and PR series.
Summary by CodeRabbit
Bug Fixes & Improvements
Style