Skip to content

Fix some bugs in charts UI#44329

Merged
sgress454 merged 5 commits intomainfrom
sgress454/chart-unreleased-bugs
Apr 28, 2026
Merged

Fix some bugs in charts UI#44329
sgress454 merged 5 commits intomainfrom
sgress454/chart-unreleased-bugs

Conversation

@sgress454
Copy link
Copy Markdown
Contributor

@sgress454 sgress454 commented Apr 28, 2026

Related issue: Resolves #44249

Checklist for submitter

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

  • Changes file added for user-visible changes in changes/, orbit/changes/ or ee/fleetd-chrome/changes.
    See Changes files for more information.
    n/a, unreleased

Testing

  • Added/updated automated tests
    not worth it for style fixes and accidental content removal

  • Where appropriate, automated tests simulate multiple hosts and test for host isolation (updates to one hosts's records do not affect another)

  • QA'd all new/changed functionality manually

    • can click on hosts enrolled labels and bars to go to the appropriate hosts list
    • no more weird focus rectangles on hosts enrolled chart
    • hosts enrolled chart y-axis respects dark mode
    • metrics cards returned to dashboard
    • hovering over a bar on the hosts enrolled chart shows a tooltip with the # of hosts in that platform

For unreleased bug fixes in a release candidate, one of:

  • Confirmed that the fix is not expected to adversely impact load test results

Summary by CodeRabbit

  • New Features

    • Hosts Enrolled card: click platform bars or Y-axis labels to navigate to platform-specific host lists; interactive tooltips show platform and host count.
  • UI Improvements

    • Streamlined dashboard host-count display with a small loading spinner while summaries load.
    • Improved interactivity cues: hover styles, pointer cursor, and refined tooltip visuals for chart elements.

Copilot AI review requested due to automatic review settings April 28, 2026 20:47
@sgress454 sgress454 requested a review from a team as a code owner April 28, 2026 20:47
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.

Comment on lines -140 to -146
const [macCount, setMacCount] = useState(0);
const [windowsCount, setWindowsCount] = useState(0);
const [linuxCount, setLinuxCount] = useState(0);
const [chromeCount, setChromeCount] = useState(0);
const [iosCount, setIosCount] = useState(0);
const [ipadosCount, setIpadosCount] = useState(0);
const [androidCount, setAndroidCount] = useState(0);
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.

This and the rest of the large deletions are just from removing the PlatformHostCounts element (the cards that showed the # of mac, windows and linux hosts). They should have been removed previously.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 28, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 66.78%. Comparing base (9609f0a) to head (af2b13c).
⚠️ Report is 15 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff            @@
##             main   #44329    +/-   ##
========================================
  Coverage   66.78%   66.78%            
========================================
  Files        2630     2630            
  Lines      211232   211226     -6     
  Branches     9510     9387   -123     
========================================
- Hits       141063   141062     -1     
+ Misses      57348    57343     -5     
  Partials    12821    12821            
Flag Coverage Δ
frontend 54.74% <ø> (+<0.01%) ⬆️

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.

Comment on lines +888 to +892
<HostsEnrolledCard
counts={totalCounts}
builtInLabels={labels}
currentTeamId={teamIdForApi}
router={router}
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.

adding new props to allow clicking on elements of the hosts enrolled chart to go to hosts list page

onLabelClick: (index: number) => void;
}

const ClickableYAxisTick = ({
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.

new element to use for the y-axis ticks, to make them clickable when there's data.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 28, 2026

Walkthrough

The PR simplifies dashboard host-count rendering by removing per-platform host count state and the PlatformHostCounts section, restoring MetricsHostCounts within HostCountCards. HostsEnrolledCard now accepts router, optional builtInLabels, and optional currentTeamId, adds click handling for bars and Y-axis ticks to navigate to label-filtered host lists, and renders a tooltip with platform counts. A __host-sections wrapper shows a loading spinner while fetching host summary. SCSS updates add theme-driven axis colors, pointer cursors for clickable elements, tooltip styling, and remove focus outlines on chart SVG elements.

Possibly related PRs

  • Add dashboard charts frontend #43878: Introduced HostsEnrolledCard and initial dashboard chart/layout changes; overlaps with this PR’s updates to DashboardPage and HostsEnrolledCard props/behavior.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Fix some bugs in charts UI' is vague and generic, using the non-descriptive term 'bugs' without specifying which bugs or what UI changes were made. Use a more specific title describing the primary bug fixes, such as 'Fix chart interactivity, focus states, and restore metrics cards on dashboard'.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR directly addresses all objectives from issue #44249: makes chart rows clickable [DashboardPage.tsx, HostsEnrolledCard.tsx], removes focus rectangles [_styles.scss], enables dark mode y-axis styling [_styles.scss], restores MetricsHostCounts [DashboardPage.tsx], and adds tooltip for per-platform counts [HostsEnrolledCard.tsx].
Out of Scope Changes check ✅ Passed All changes are directly scoped to resolving the five UI issues identified in #44249; no unrelated or extraneous modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The pull request description follows the template structure and includes related issue, testing checklist with manual QA details, and load test confirmation.

✏️ 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/chart-unreleased-bugs

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.

🧹 Nitpick comments (1)
frontend/pages/DashboardPage/cards/HostsEnrolledCard/_styles.scss (1)

22-32: Consider preserving focus indicators for keyboard accessibility.

Suppressing all focus outlines with outline: none !important removes visual feedback for keyboard users navigating the chart. While this addresses the "undesirable focus rectangles" bug, completely removing focus indicators can create accessibility barriers.

Consider providing a custom focus style (e.g., a subtle box-shadow or border) instead of completely suppressing the outline, or ensure these chart elements are not focusable via keyboard (tabindex="-1") if they're only intended for mouse interaction.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 95a144d6-5a89-496c-a3eb-669db123c9b7

📥 Commits

Reviewing files that changed from the base of the PR and between c0ecbfc and 5aaa148.

📒 Files selected for processing (3)
  • frontend/pages/DashboardPage/DashboardPage.tsx
  • frontend/pages/DashboardPage/cards/HostsEnrolledCard/HostsEnrolledCard.tsx
  • frontend/pages/DashboardPage/cards/HostsEnrolledCard/_styles.scss

cdcme
cdcme previously approved these changes Apr 28, 2026
<Tooltip
content={<HostsEnrolledTooltip />}
cursor={false}
isAnimationActive={false}
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.

without this the tooltip "swoops" in from the side in a very weird manner

@sgress454
Copy link
Copy Markdown
Contributor Author

Added one more thing: hover on the hosts enrolled bars to see the actual counts. We lost this info when we removed the per-platform host count cards.

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

🤖 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/HostsEnrolledCard/HostsEnrolledCard.tsx`:
- Around line 167-170: The bar rendering/interaction logic must use the same
guard as isTickClickable to avoid showing clickable affordances when
builtInLabels is missing; update the bar hover/cursor and onClick checks (the
code that currently only checks datum.count > 0 around the bar render and the
code path that calls navigateToPlatform) to instead call isTickClickable(index)
or replicate its logic (ensure datum exists, datum.count is truthy, and
getLabelId(datum.platform) !== undefined) so bars only show pointer/hover and
invoke navigateToPlatform when a resolved label id exists; apply the same change
to the other rendering block around navigateToPlatform referenced in the comment
(the block around lines 210-224).
- Around line 100-126: The ClickableYAxisTick component only handles pointer
clicks; make it keyboard-activatable by adding focus and keyboard handlers: when
isClickable(payload.index) is true, render the outer <g> with tabIndex={0},
role="link" (or "button" if semantics prefer), and an onKeyDown handler that
calls onLabelClick(payload.index) when Enter or Space is pressed; also set
aria-disabled or omit role/tabIndex when not clickable and ensure the clickable
className remains for focus styling so keyboard users can see focus state.
🪄 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: d5f64650-2697-4753-b334-da477738c8cc

📥 Commits

Reviewing files that changed from the base of the PR and between 5aaa148 and af2b13c.

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

Comment on lines +100 to +126
const ClickableYAxisTick = ({
x = 0,
y = 0,
payload,
isClickable,
onLabelClick,
}: IYAxisTickProps): JSX.Element => {
if (!payload) return <g />;
const clickable = isClickable(payload.index);
return (
<g
transform={`translate(${x},${y})`}
onClick={clickable ? () => onLabelClick(payload.index) : undefined}
>
<text
x={0}
y={0}
dy={4}
textAnchor="end"
fontSize={14}
className={clickable ? `${baseClass}__tick--clickable` : undefined}
>
{payload.value}
</text>
</g>
);
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Make the custom Y-axis tick keyboard-activatable.

This adds a new interactive control, but it only handles pointer clicks. Keyboard users cannot focus or activate these platform links.

Suggested fix
 const ClickableYAxisTick = ({
   x = 0,
   y = 0,
   payload,
   isClickable,
   onLabelClick,
 }: IYAxisTickProps): JSX.Element => {
   if (!payload) return <g />;
   const clickable = isClickable(payload.index);
+  const handleActivate = () => {
+    if (clickable) onLabelClick(payload.index);
+  };
+
   return (
     <g
       transform={`translate(${x},${y})`}
-      onClick={clickable ? () => onLabelClick(payload.index) : undefined}
+      onClick={clickable ? handleActivate : undefined}
+      onKeyDown={
+        clickable
+          ? (e) => {
+              if (e.key === "Enter" || e.key === " ") {
+                e.preventDefault();
+                handleActivate();
+              }
+            }
+          : undefined
+      }
+      tabIndex={clickable ? 0 : -1}
+      role={clickable ? "button" : undefined}
+      aria-label={clickable ? `View ${payload.value} hosts` : undefined}
     >
       <text
         x={0}
         y={0}
         dy={4}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const ClickableYAxisTick = ({
x = 0,
y = 0,
payload,
isClickable,
onLabelClick,
}: IYAxisTickProps): JSX.Element => {
if (!payload) return <g />;
const clickable = isClickable(payload.index);
return (
<g
transform={`translate(${x},${y})`}
onClick={clickable ? () => onLabelClick(payload.index) : undefined}
>
<text
x={0}
y={0}
dy={4}
textAnchor="end"
fontSize={14}
className={clickable ? `${baseClass}__tick--clickable` : undefined}
>
{payload.value}
</text>
</g>
);
};
const ClickableYAxisTick = ({
x = 0,
y = 0,
payload,
isClickable,
onLabelClick,
}: IYAxisTickProps): JSX.Element => {
if (!payload) return <g />;
const clickable = isClickable(payload.index);
const handleActivate = () => {
if (clickable) onLabelClick(payload.index);
};
return (
<g
transform={`translate(${x},${y})`}
onClick={clickable ? handleActivate : undefined}
onKeyDown={
clickable
? (e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
handleActivate();
}
}
: undefined
}
tabIndex={clickable ? 0 : -1}
role={clickable ? "button" : undefined}
aria-label={clickable ? `View ${payload.value} hosts` : undefined}
>
<text
x={0}
y={0}
dy={4}
textAnchor="end"
fontSize={14}
className={clickable ? `${baseClass}__tick--clickable` : undefined}
>
{payload.value}
</text>
</g>
);
};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/pages/DashboardPage/cards/HostsEnrolledCard/HostsEnrolledCard.tsx`
around lines 100 - 126, The ClickableYAxisTick component only handles pointer
clicks; make it keyboard-activatable by adding focus and keyboard handlers: when
isClickable(payload.index) is true, render the outer <g> with tabIndex={0},
role="link" (or "button" if semantics prefer), and an onKeyDown handler that
calls onLabelClick(payload.index) when Enter or Space is pressed; also set
aria-disabled or omit role/tabIndex when not clickable and ensure the clickable
className remains for focus styling so keyboard users can see focus state.

Comment on lines +167 to +170
const isTickClickable = (index: number) => {
const datum = data[index];
if (!datum || !datum.count) return false;
return getLabelId(datum.platform) !== undefined;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Align bar click affordances with the actual navigation guard.

isTickClickable correctly requires both a non-zero count and a resolved label id, but the bars only check count > 0. Since builtInLabels is optional, a bar can show pointer/hover affordances and still no-op in navigateToPlatform.

Suggested fix
+  const isBarClickable = ({ platform, count }: IPlatformDatum) => {
+    return count > 0 && getLabelId(platform) !== undefined;
+  };
+
   const isTickClickable = (index: number) => {
     const datum = data[index];
     if (!datum || !datum.count) return false;
     return getLabelId(datum.platform) !== undefined;
   };
@@
           <Bar
             dataKey="count"
             radius={[0, 4, 4, 0]}
             barSize={16}
             isAnimationActive={false}
             activeBar={{ fill: BAR_HOVER_COLOR }}
-            onClick={(d) => handleBarClick(d.payload as IPlatformDatum)}
+            onClick={(d) => {
+              const datum = d.payload as IPlatformDatum;
+              if (isBarClickable(datum)) handleBarClick(datum);
+            }}
           >
             {data.map((entry) => (
               <Cell
                 key={entry.label}
                 fill={BAR_COLOR}
                 className={
-                  entry.count > 0 ? `${baseClass}__bar--clickable` : undefined
+                  isBarClickable(entry)
+                    ? `${baseClass}__bar--clickable`
+                    : undefined
                 }
               />
             ))}

Also applies to: 210-224

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

In `@frontend/pages/DashboardPage/cards/HostsEnrolledCard/HostsEnrolledCard.tsx`
around lines 167 - 170, The bar rendering/interaction logic must use the same
guard as isTickClickable to avoid showing clickable affordances when
builtInLabels is missing; update the bar hover/cursor and onClick checks (the
code that currently only checks datum.count > 0 around the bar render and the
code path that calls navigateToPlatform) to instead call isTickClickable(index)
or replicate its logic (ensure datum exists, datum.count is truthy, and
getLabelId(datum.platform) !== undefined) so bars only show pointer/hover and
invoke navigateToPlatform when a resolved label id exists; apply the same change
to the other rendering block around navigateToPlatform referenced in the comment
(the block around lines 210-224).

@sgress454 sgress454 merged commit dd2e21d into main Apr 28, 2026
19 checks passed
@sgress454 sgress454 deleted the sgress454/chart-unreleased-bugs branch April 28, 2026 22:59
sgress454 added a commit that referenced this pull request Apr 29, 2026
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.

Chart and Dashboard UI issues

3 participants