Skip to content

Vulnerability exposure chart front-end#44261

Merged
lukeheath merged 7 commits into
mainfrom
sgress454/cve-chart-frontend
Apr 30, 2026
Merged

Vulnerability exposure chart front-end#44261
lukeheath merged 7 commits into
mainfrom
sgress454/cve-chart-frontend

Conversation

@sgress454
Copy link
Copy Markdown
Contributor

@sgress454 sgress454 commented Apr 27, 2026

Related issue: For #44125

Checklist for submitter

If some of the following don't apply, delete the relevant line.

Testing

  • Added/updated automated tests
  • QA'd all new/changed functionality manually
    • with backend PR and test data:

Summary by CodeRabbit

  • New Features

    • Added a CVE dataset visualization with its own red theme and tailored tooltip copy.
    • Tooltips now show host counts alongside computed percentages.
  • Improvements

    • Chart theming is customizable per dataset.
    • Checkerboard tooltips align smartly to avoid overflow and support custom tooltip formats.
    • Percentage handling now safely falls back to 0 when totals are missing.

Copilot AI review requested due to automatic review settings April 27, 2026 22:07
@sgress454 sgress454 requested a review from a team as a code owner April 27, 2026 22:07
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 27, 2026

Codecov Report

❌ Patch coverage is 59.09091% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.77%. Comparing base (ee8c50e) to head (e849fae).
⚠️ Report is 179 commits behind head on main.

Files with missing lines Patch % Lines
.../pages/DashboardPage/cards/ChartCard/ChartCard.tsx 25.00% 5 Missing and 1 partial ⚠️
.../DashboardPage/cards/ChartCard/CheckerboardViz.tsx 78.57% 3 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main   #44261   +/-   ##
=======================================
  Coverage   66.77%   66.77%           
=======================================
  Files        2628     2629    +1     
  Lines      211157   211196   +39     
  Branches     9498     9516   +18     
=======================================
+ Hits       141000   141034   +34     
- Misses      57335    57339    +4     
- Partials    12822    12823    +1     
Flag Coverage Δ
frontend 54.83% <59.09%> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds front-end support for a new “Vulnerability exposure” dashboard chart by extending the existing ChartCard/Checkerboard visualization with theming and richer tooltip formatting.

Changes:

  • Introduces chart theming (green/red) and a customizable tooltip formatter per dataset.
  • Adds a new “Vulnerability exposure” dataset to the dashboard chart selector and wires tooltip formatting + red theme into the checkerboard viz.
  • Updates checkerboard styling to use CSS custom properties for level colors and improves tooltip alignment near edges.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
frontend/pages/DashboardPage/cards/ChartCard/types.ts Adds ChartTheme, TooltipFormatter, and total support in formatted datapoints/dataset config.
frontend/pages/DashboardPage/cards/ChartCard/_styles.scss Adds link styling for react-tooltip, tooltip alignment modifiers, and themeable checkerboard color levels via CSS variables.
frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tsx Adds theme support, tooltip formatter support, and edge-aware tooltip alignment; threads value/total into hovered cells.
frontend/pages/DashboardPage/cards/ChartCard/ChartCard.tsx Adds new “Vulnerability exposure” dataset and passes theme/tooltip formatting into the visualization layer.
Comments suppressed due to low confidence (2)

frontend/pages/DashboardPage/cards/ChartCard/ChartCard.tsx:219

  • vizProps now includes theme and tooltipFormatter, but it is spread into both <CheckerboardViz> and <LineChartViz>. LineChartViz only accepts { data, selectedDays }, so this will fail TypeScript type-checking (and/or pass unexpected props). Consider splitting props per visualization (common props vs checkerboard-only props) or updating LineChartViz props to explicitly accept (and ignore) these optional fields.
    const vizProps = {
      data: formattedData,
      selectedDays: CHART_DAYS,
      theme: currentDataset.theme,
      tooltipFormatter: currentDataset.tooltipFormatter,
    };

    switch (currentDataset.defaultChartType) {
      case "checkerboard":
        return <CheckerboardViz {...vizProps} />;
      case "line":
      default:
        return <LineChartViz {...vizProps} />;
    }

frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tsx:35

  • ICellData now requires a value, but the 24h branch (if (is24h) { ... }) still constructs cells without a value field. This should be a TypeScript error and will also break tooltip formatting for 24h charts; populate value (and total if needed) for those cells too.
interface ICellData {
  dayIndex: number;
  hourRow: number;
  value: number;
  total?: number;
  percentage: number;
  dayLabel: string;
  hourLabel: string;
}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tsx
Comment thread frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tsx
Comment thread frontend/pages/DashboardPage/cards/ChartCard/ChartCard.tsx
Comment thread frontend/pages/DashboardPage/cards/ChartCard/ChartCard.tsx Outdated
Comment thread frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tsx
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 27, 2026

Walkthrough

This change wires per-dataset theming and tooltip formatters through ChartCard into visualizations, adds a red-themed cve dataset and a formatter for uptime, and ensures formatted chart datapoints carry total (derived from chartData.total_hosts) with percentage computed defensively when total is missing. CheckerboardViz gains an optional theme prop, tooltip alignment logic, extended cell data (value, optional total, percentage), and an optional tooltipFormatter. SCSS adds theme classes and tooltip alignment styles. Types add ChartTheme, TooltipFormatter, and extend IDataSet/IFormattedDataPoint.

Possibly related PRs

  • PR #43878: Prior changes that introduced the base ChartCard, CheckerboardViz, styles, and tests which this PR extends by adding per-dataset theme/tooltip formatter support and passing total to formatted datapoints.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is incomplete; while it references related issues and notes testing was performed, it lacks substantive detail about what was implemented, changed, or added in this PR. Add a clear summary of the changes (e.g., new theme and tooltip formatter support, CVE dataset addition, styling updates) to help reviewers understand the implementation scope.
Title check ❓ Inconclusive The title 'Vulnerability exposure chart front-end' is vague and overly broad; it describes the general feature area but not the specific changes made (theming, tooltip formatting, CVE dataset support). Consider a more specific title like 'Add theme and custom tooltip support to vulnerability exposure chart' to better reflect the key implementation details.
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sgress454/cve-chart-frontend

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
frontend/pages/DashboardPage/cards/ChartCard/ChartCard.tsx (1)

178-186: ⚠️ Potential issue | 🟡 Minor

Edge case: total_hosts == 0 produces misleading tooltip.

chartData.total_hosts || 1 falls back to 1 when total_hosts is 0 (or any falsy value). This avoids divide-by-zero for the percentage, but the resulting total: totalHosts then becomes 1 in the data points, so tooltips will render 0 / 1 hosts even when there are genuinely zero hosts in scope.

If a 0-host case is reachable (e.g., a team or filtered selection with no hosts), consider keeping the original total for display while only guarding the divisor:

♻️ Suggested adjustment
-    const totalHosts = chartData.total_hosts || 1;
+    const totalHosts = chartData.total_hosts ?? 0;
+    const divisor = totalHosts || 1;
     return chartData.data.map((point) => {
       const date = parseISO(point.timestamp);
       return {
         timestamp: point.timestamp,
         label: format(date, "MMM d, h:mm a"),
         value: point.value,
-        percentage: Math.round((point.value / totalHosts) * 100),
+        percentage: Math.round((point.value / divisor) * 100),
         total: totalHosts,
       };
     });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/pages/DashboardPage/cards/ChartCard/ChartCard.tsx` around lines 178
- 186, The code currently sets totalHosts = chartData.total_hosts || 1 which
masks real zero totals and causes tooltips to show "0 / 1 hosts"; instead in
ChartCard keep the original total value for display (use chartData.total_hosts
or 0/undefined as-is) and only use a separate safe divisor (e.g.,
safeTotalForDivision = chartData.total_hosts || 1) when computing percentage;
update the map that builds each point so percentage uses safeTotalForDivision
while total uses chartData.total_hosts (or 0) so tooltips reflect the actual
host count.
frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tsx (1)

100-116: ⚠️ Potential issue | 🟠 Major

24h branch drops value/total from cells — tooltip will render undefined / undefined hosts.

ICellData (line 27-35) declares value: number as required, but the 24h cell construction here returns objects without value or total. Two consequences:

  1. This should be a TypeScript error against cells: ICellData[] (missing required property value). If the build is currently passing, your tsconfig is permissive enough to allow it, but the multi-day branch (line 164-172) does set both fields, so the omission is clearly unintentional.
  2. At runtime, when selectedDays === 1, the new dataset tooltipFormatter calls (e.g., cve's ({value} / {total} hosts)) will resolve value and total to undefined, producing strings like 0% exposed (undefined / undefined hosts).

Today this is masked because CHART_DAYS is hardcoded to 30 in ChartCard.tsx, but the comment in ChartCard.tsx (line 28-29) explicitly anticipates configurable ranges, so this lands as a latent bug ready to bite the next person who wires up day selection.

🐛 Suggested fix
       const cells: ICellData[] = data.map((point, i) => {
         const date = parseISO(point.timestamp);
         return {
           dayIndex: 0,
           hourRow: i,
           percentage: point.percentage,
+          value: point.value,
+          total: point.total,
           dayLabel: format(date, "MMM d"),
           hourLabel: formatHourLabel(date.getHours()),
         };
       });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tsx` around
lines 100 - 116, The 24h branch builds ICellData objects without the required
value and total fields causing undefined tooltips; update the 24h cell
construction in CheckerboardViz (the const cells: ICellData[] = data.map(...)
block) to include value and total (e.g., set value: point.value and total:
point.total or sensible defaults like 0 if those props might be missing) so each
cell matches the ICellData shape used by tooltipFormatter and the multi-day
branch.
🧹 Nitpick comments (3)
frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tsx (2)

41-49: Reuse the exported TooltipFormatter type instead of redeclaring its shape inline.

types.ts already exports TooltipFormatter with this exact signature. Inlining a duplicate here means the two will drift independently if the formatter contract ever changes (e.g., a new field is added).

♻️ Suggested refactor
-import { ChartTheme, IFormattedDataPoint } from "./types";
+import { ChartTheme, IFormattedDataPoint, TooltipFormatter } from "./types";
@@
 interface ICheckerboardVizProps {
   data: IFormattedDataPoint[];
   selectedDays: number;
   theme?: ChartTheme;
-  tooltipFormatter?: ({
-    value,
-    total,
-    percentage,
-  }: {
-    value: number;
-    total?: number;
-    percentage?: number;
-  }) => string | React.ReactNode;
+  tooltipFormatter?: TooltipFormatter;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tsx` around
lines 41 - 49, The prop type for tooltipFormatter in CheckerboardViz is
redeclared inline; instead import and reuse the exported TooltipFormatter type
from types.ts to avoid duplication. Update the component's props signature to
replace the inline shape with the imported TooltipFormatter (ensure you add an
import for TooltipFormatter) and keep the prop name tooltipFormatter unchanged
so consumers and the component implementation still work the same.

202-223: Edge-zone heuristic: hardcoded 100px threshold is decoupled from cell width.

EDGE_ZONE = 100 is a fixed pixel buffer applied regardless of cellW/scale, which means in wide mode (WIDE_MULTIPLIER = 1.5) the "edge" zone effectively shrinks relative to actual cell footprint, and in very narrow containers it could cover most of the chart. Consider deriving it from cellW (e.g., Math.max(80, cellW * 4)) or hoisting it to a named constant near the other layout constants (CELL_W, CELL_GAP, etc.) so the layout intent stays in one place.

Also worth confirming visually: when tooltipAlign === "right", the SCSS applies transform: translate(-100%, -100%) so the tooltip's right edge aligns with tooltipPos.x (the cell center). Near the actual right edge that still leaves the tooltip extending leftward across the chart, which matches the comment — but since cellCenterX here is rect.left - containerRect.left + cellW / 2 (cell center, not right edge), the tooltip's right side will sit at the cell center, not the cell's right edge. Just flagging that the visual anchor point differs from "right edge of the cell" in case that surprises you during QA.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tsx` around
lines 202 - 223, The EDGE_ZONE heuristic in handleMouseEnter is a fixed 100px
which doesn't scale with cell width/scale; replace the hardcoded value with a
derived value (e.g., const EDGE_ZONE = Math.max(80, cellW * 4)) or hoist a named
constant next to CELL_W/CELL_GAP/WIDE_MULTIPLIER so layout intent is
centralized, then use that derived EDGE_ZONE when deciding tooltipAlign. Also
clarify the anchor point: currently cellCenterX is used (rect.left -
containerRect.left + cellW / 2) but the SCSS "right" alignment positions the
tooltip's right edge at tooltipPos.x, so if you want the tooltip to anchor to
the cell's right edge instead, compute and use cellRightX (rect.left -
containerRect.left + cellW) for tooltipPos.x; keep tooltipAlign logic otherwise.
frontend/pages/DashboardPage/cards/ChartCard/ChartCard.tsx (1)

44-92: Optional: extract a shared tooltip formatter helper.

The uptime and cve tooltipFormatter implementations are structurally identical except for the verb (active vs exposed). Consider a small helper to keep them aligned as more datasets are added.

♻️ Example refactor
+const buildPctTooltip = (verb: string): TooltipFormatter => ({
+  value,
+  total,
+  percentage,
+}) => (
+  <>
+    {percentage}% {verb}
+    <br />({value} / {total} hosts)
+  </>
+);
+
 const DATASETS: IDataSet[] = [
   {
     name: "uptime",
     ...
-    tooltipFormatter: ({ value, total, percentage }: { ... }) => (
-      <>{percentage}% active<br />({value} / {total} hosts)</>
-    ),
+    tooltipFormatter: buildPctTooltip("active"),
   },
   {
     name: "cve",
     ...
-    tooltipFormatter: ({ value, total, percentage }: { ... }) => (
-      <>{percentage}% exposed<br />({value} / {total} hosts)</>
-    ),
+    tooltipFormatter: buildPctTooltip("exposed"),
     theme: "red",
   },
 ];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/pages/DashboardPage/cards/ChartCard/ChartCard.tsx` around lines 44 -
92, Extract the duplicated tooltipFormatter into a reusable helper (e.g.,
makeTooltipFormatter or createTooltipFormatter) that accepts the differing verb
string ("active" or "exposed") and returns the formatter function with the same
signature ({ value, total, percentage }: { value: number; total?: number;
percentage?: number }) => JSX.Element; replace the inline tooltipFormatter for
the uptime and cve chart objects with calls to this helper (e.g.,
tooltipFormatter: makeTooltipFormatter("active")). Ensure the helper is
exported/defined in the same module (ChartCard.tsx) or nearby, preserves types,
and that both chart objects keep their existing behavior and theme fields
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/pages/DashboardPage/cards/ChartCard/_styles.scss`:
- Around line 233-254: The comment claims level-4 is aliased to
$core-fleet-green but the CSS custom property in &--theme-green (and
&--theme-red) uses a literal hex for --level-4 (`#009a7d` / `#9a0000`); update
_styles.scss so the comment matches the code: either change the &--theme-green
--level-4 value to use the SCSS token ($core-fleet-green) via interpolation
(--level-4: #{$core-fleet-green};) or remove/modify the sentence mentioning the
alias so it no longer states level-4 is aliased to $core-fleet-green. Ensure you
reference the &--theme-green block and the --level-4 property when making the
change.

In `@frontend/pages/DashboardPage/cards/ChartCard/ChartCard.tsx`:
- Around line 66-74: The anchor in ChartCard (the <a> inside the ChartCard
component) currently points at a hardcoded commit SHA and uses a named target;
update the href to a stable, maintained URL (for example the file at a released
tag or a documentation page the team maintains) instead of the specific commit
SHA, and change the link target handling to open safely by using target="_blank"
together with rel="noopener noreferrer" (or otherwise ensure rel contains both
noopener and noreferrer) to prevent window.opener access when users click the
external link.

---

Outside diff comments:
In `@frontend/pages/DashboardPage/cards/ChartCard/ChartCard.tsx`:
- Around line 178-186: The code currently sets totalHosts =
chartData.total_hosts || 1 which masks real zero totals and causes tooltips to
show "0 / 1 hosts"; instead in ChartCard keep the original total value for
display (use chartData.total_hosts or 0/undefined as-is) and only use a separate
safe divisor (e.g., safeTotalForDivision = chartData.total_hosts || 1) when
computing percentage; update the map that builds each point so percentage uses
safeTotalForDivision while total uses chartData.total_hosts (or 0) so tooltips
reflect the actual host count.

In `@frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tsx`:
- Around line 100-116: The 24h branch builds ICellData objects without the
required value and total fields causing undefined tooltips; update the 24h cell
construction in CheckerboardViz (the const cells: ICellData[] = data.map(...)
block) to include value and total (e.g., set value: point.value and total:
point.total or sensible defaults like 0 if those props might be missing) so each
cell matches the ICellData shape used by tooltipFormatter and the multi-day
branch.

---

Nitpick comments:
In `@frontend/pages/DashboardPage/cards/ChartCard/ChartCard.tsx`:
- Around line 44-92: Extract the duplicated tooltipFormatter into a reusable
helper (e.g., makeTooltipFormatter or createTooltipFormatter) that accepts the
differing verb string ("active" or "exposed") and returns the formatter function
with the same signature ({ value, total, percentage }: { value: number; total?:
number; percentage?: number }) => JSX.Element; replace the inline
tooltipFormatter for the uptime and cve chart objects with calls to this helper
(e.g., tooltipFormatter: makeTooltipFormatter("active")). Ensure the helper is
exported/defined in the same module (ChartCard.tsx) or nearby, preserves types,
and that both chart objects keep their existing behavior and theme fields
unchanged.

In `@frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tsx`:
- Around line 41-49: The prop type for tooltipFormatter in CheckerboardViz is
redeclared inline; instead import and reuse the exported TooltipFormatter type
from types.ts to avoid duplication. Update the component's props signature to
replace the inline shape with the imported TooltipFormatter (ensure you add an
import for TooltipFormatter) and keep the prop name tooltipFormatter unchanged
so consumers and the component implementation still work the same.
- Around line 202-223: The EDGE_ZONE heuristic in handleMouseEnter is a fixed
100px which doesn't scale with cell width/scale; replace the hardcoded value
with a derived value (e.g., const EDGE_ZONE = Math.max(80, cellW * 4)) or hoist
a named constant next to CELL_W/CELL_GAP/WIDE_MULTIPLIER so layout intent is
centralized, then use that derived EDGE_ZONE when deciding tooltipAlign. Also
clarify the anchor point: currently cellCenterX is used (rect.left -
containerRect.left + cellW / 2) but the SCSS "right" alignment positions the
tooltip's right edge at tooltipPos.x, so if you want the tooltip to anchor to
the cell's right edge instead, compute and use cellRightX (rect.left -
containerRect.left + cellW) for tooltipPos.x; keep tooltipAlign logic otherwise.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3bd499f6-10f5-4b4f-a0fb-d08ea4c31202

📥 Commits

Reviewing files that changed from the base of the PR and between 1c89b79 and 7fbb2de.

📒 Files selected for processing (4)
  • frontend/pages/DashboardPage/cards/ChartCard/ChartCard.tsx
  • frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tsx
  • frontend/pages/DashboardPage/cards/ChartCard/_styles.scss
  • frontend/pages/DashboardPage/cards/ChartCard/types.ts

Comment thread frontend/pages/DashboardPage/cards/ChartCard/_styles.scss
Comment thread frontend/pages/DashboardPage/cards/ChartCard/ChartCard.tsx
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tsx (1)

97-105: ⚠️ Potential issue | 🔴 Critical

24h cell mapping omits required value field.

The 24h branch (lines 97–105) returns ICellData objects without the required value field. Input data points from IFormattedDataPoint[] have value: number, but the mapped cells exclude it. When tooltipFormatter is invoked with hoveredCell.value for a 24h view cell, it receives undefined, breaking the formatter's contract that expects value: number.

Proposed fix
       const cells: ICellData[] = data.map((point, i) => {
         const date = parseISO(point.timestamp);
         return {
           dayIndex: 0,
           hourRow: i,
+          value: point.value,
+          total: point.total,
           percentage: point.percentage,
           dayLabel: format(date, "MMM d"),
           hourLabel: formatHourLabel(date.getHours()),
         };
       });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tsx` around
lines 97 - 105, The 24h mapping in CheckerboardViz.tsx builds ICellData objects
without the required value field, causing tooltipFormatter (which reads
hoveredCell.value) to get undefined; update the data.map inside the 24h branch
(the const cells: ICellData[] = data.map(...) block) to include value:
point.value on each returned object so each ICellData contains the numeric value
from IFormattedDataPoint and satisfies tooltipFormatter's contract.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/pages/DashboardPage/cards/ChartCard/ChartCard.tsx`:
- Around line 44-57: The tooltipFormatter in ChartCard.tsx currently uses a
truthy check (total ? ... : 0) which collapses total=0 and total=undefined into
"0 hosts" and can hide a non-zero value; change the logic to distinguish
undefined from zero (e.g., if total !== undefined show `${value} / ${total}`
else show `${value}` or an "unknown" total string) so a non-zero value isn't
masked, and apply the same fix to the other tooltip/formatter occurrence in the
same file (the second formatter block around lines 78-91).

---

Outside diff comments:
In `@frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tsx`:
- Around line 97-105: The 24h mapping in CheckerboardViz.tsx builds ICellData
objects without the required value field, causing tooltipFormatter (which reads
hoveredCell.value) to get undefined; update the data.map inside the 24h branch
(the const cells: ICellData[] = data.map(...) block) to include value:
point.value on each returned object so each ICellData contains the numeric value
from IFormattedDataPoint and satisfies tooltipFormatter's contract.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f8c0064e-0395-4300-8bbb-9441af2b3aa7

📥 Commits

Reviewing files that changed from the base of the PR and between 7fbb2de and e849fae.

📒 Files selected for processing (4)
  • frontend/pages/DashboardPage/cards/ChartCard/ChartCard.tsx
  • frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tests.tsx
  • frontend/pages/DashboardPage/cards/ChartCard/CheckerboardViz.tsx
  • frontend/pages/DashboardPage/cards/ChartCard/_styles.scss
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/pages/DashboardPage/cards/ChartCard/_styles.scss

Comment thread frontend/pages/DashboardPage/cards/ChartCard/ChartCard.tsx
Comment on lines +125 to 133

.react-tooltip {
a {
color: $core-fleet-white;
display: inline;
font-size: $xx-small;
}
}
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

setting tooltip links to be white

sgress454 added a commit that referenced this pull request Apr 29, 2026
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** For #43769

# Details

Adds methods to collect data for the `cve` dataset. As with all sets
this is collected at hourly granularity, but unlike the `uptime` set,
the `cve` set uses the "snapshot" strategy so that we record at most one
change (the most recent) per hour.

For this first iteration, we are _recording_ data for all CVEs (i.e.,
which hosts were exposed to which CVEs at a given time), but we are only
_reporting_ a subset of CVEs for the dashboard chart. See [this
comment](#44124 (comment))
for more info.

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.

- [X] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.

## Testing

- [X] Added/updated automated tests
- [X] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)

- [X] QA'd all new/changed functionality manually
- [X] Spot-checked the CVEs chosen by the `trackedCVESoftwareMatchers`
and didn't find any outside of the expected
- [X] With [front-end PR](#44261),
generated chart:
<img width="706" height="421" alt="image"
src="https://github.com/user-attachments/assets/539d9877-6573-4406-a159-1d2a711a045f"
/>



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Host vulnerability (CVE) chart added to the dashboard; CVE chart data
collection is now active.
  * Critical CVE tracking surfaces high-severity vulnerabilities.

* **Improvements**
* CVE chart refreshes every 3 hours (was daily) for more timely
insights.
* Snapshot collection reconciles and closes prior data during empty runs
to keep charts accurate.
* CVE queries may produce zero datapoints when no tracked CVEs exist,
without affecting other metrics.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@lukeheath lukeheath merged commit 5ac9991 into main Apr 30, 2026
19 checks passed
@lukeheath lukeheath deleted the sgress454/cve-chart-frontend branch April 30, 2026 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants