## Problem
Android hosts show different timestamps for **Last seen** and **Last
fetched** on the host details page. For Android devices (which don't use
osquery check-in), both values should match because they're updated by
the same MDM sync operation.
Fixesfleetdm/fleet#43195
## Root Cause
`host_seen_times` is the table that powers the `seen_time` (Last seen)
value. For regular hosts, this is updated by osquery check-in. Android
hosts never populated this table, so `seen_time` fell back to
`hosts.created_at`, causing a mismatch with `detail_updated_at` (Last
fetched).
## Changes
- **`NewAndroidHost`** — after inserting the host, also insert into
`host_seen_times` with the same `detail_updated_at` value.
- **`UpdateAndroidHost`** — after updating the host, upsert
`host_seen_times` with the new `detail_updated_at`.
- **New test `AndroidLastSeenMatchesLastFetched`** — verifies
`host_seen_times.seen_time` matches `detail_updated_at` for both
`NewAndroidHost` and `UpdateAndroidHost` paths.
## Testing
- Added `testAndroidLastSeenMatchesLastFetched` covering both paths.
- Existing Android datastore tests should continue to pass.
---
*This PR was created with AI assistance.*
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Host list now shows "Last seen" in a platform-aware way; mobile hosts
display "Last seen: Not supported" instead of unreliable timestamps.
* Hostname entries now include platform info so last-seen display is
accurate across device types.
* Improved consistency in last-seen rendering across the hosts table.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/44628)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Wahaj Ahmed <wahajahmed010@gmail.com>
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#43984
# 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.
## Testing
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Updated the setup experience "Users" card to explain automatic
creation of local accounts via identity provider credentials (PSSO),
improving clarity for admins.
* **Documentation**
* Added a learn-more link to PSSO local account documentation from the
Users card.
* **Style**
* Improved spacing and description layout within the Users card for
better readability.
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45023)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#43640
# Checklist for submitter
- [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.
## Testing
- [x] QA'd all new/changed functionality manually
I figured out that the RunScriptModal was being re-rendered without any
user events or network calls after the 2s mark.
At first I thought the parent (ScriptModalGroup.tsx) could have been the
culprit since there's a lot going on there (lots of callback functions
passed to multiple modals).
It turns out that RunScriptModal is wrapped in React.memo to avoid
re-rendering but since some of its props changed in the parent
component, this caused it to re-render and close the Actions dropdown
randomly.
To detect which where the problematic props changing, I threw this code
at the top of RunScriptModal.tsx:
```react
const prev = useRef<any>({});
useEffect(() => {
const current = {
currentUser,
hostTeamId,
onClose,
page,
setPage,
hostScriptResponse,
isFetchingHostScripts,
isLoadingHostScripts,
isError,
onClickViewScript,
onClickRunDetails,
onClickRun,
isRunningScript,
isHidden,
};
const changed = Object.entries(current).filter(
([k, v]) => prev.current[k] !== v
);
console.log(
"RunScriptModal re-render. Changed props:",
changed.map(([k]) => k)
);
prev.current = current;
});
```
and the output was:
```
RunScriptModal re-render. Changed props:
(2) ['onClickViewScript', 'onClickRunDetails']
```
So I just wrapped those two in useCallback and that fixed the issue.
https://github.com/user-attachments/assets/f6eae13e-2a60-4fda-9468-2952acdedd58
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Bug Fixes
* Fixed the Actions dropdown in the Run script modal on the Host details
page auto-closing after 2-3 seconds.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45349)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#44459
## Summary
Fixed an issue where the recovery lock password for a macOS host could
become unretrievable via the UI and API after the host was transferred
to a team with recovery lock disabled, even though the password was
still stored in the database.
## Root causes
Three bugs combined to produce the symptom:
- **Frontend visibility**: `canShowRecoveryLockPassword` gated the "Show
Recovery Lock password" action on the current team's
`enable_recovery_lock_password` setting and ignored the
`recoveryLockPasswordAvailable`
signal, so the UI option vanished whenever the host's new team had the
feature off.
- **API 404 on view**: `MarkRecoveryLockPasswordViewed` returned a
`notFound` error when its UPDATE matched zero rows. This happened as
soon as the `ClaimHostsForRecoveryLockClear` cron flipped the password
row's
`operation_type` from `install` to `remove` — causing `GET
/hosts/:id/recovery_lock_password` to 404 even though the password had
already been successfully retrieved and decrypted moments earlier in the
same
request.
- **Stale rotation deadline**: `ClaimHostsForRecoveryLockClear` left the
row's `auto_rotate_at` untouched when flipping to `remove`, so
subsequent reads still surfaced the pre-transfer view-deadline and the
UI
rendered a rotation banner promising an auto-rotation that the cron
(filtered on `operation_type='install'`) would never honor.
## Fix
- **Frontend**: updated `canShowRecoveryLockPassword` to also show the
action when a password is available, regardless of the team setting.
- **API**: changed `MarkRecoveryLockPasswordViewed` to return a zero
`time.Time` with no error when no install-state row exists. The service
skips the `AutoRotateAt` assignment in that case and explicitly nulls
any stale value loaded from the DB, so the response's `auto_rotate_at`
is omitted.
- **Data hygiene**: updated `ClaimHostsForRecoveryLockClear` to also set
`auto_rotate_at = NULL` when flipping a row to `remove`, since the
rotation deadline is meaningful only for install-state rows.
- [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.
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#45290
Just drops the mobile platforms from the platform list in the chart
filters modal.
You can still find mobile devices by searching for now, as filtering
them out is a bigger change requiring either backend work or
on-the-glass filtering + pagination which is bug-prone.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Updated platform filter options in chart filters. iOS, iPadOS, and
Android are no longer available as filter options; macOS, Windows,
Linux, and ChromeOS remain supported.
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45310)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#44801
Fixed remaining issue setting end user authentication in the UI.
The root cause was that the frontend was always sending
`enable_managed_local_account : false` even when macOS MDM was disabled.
Fix:
<img width="756" height="363" alt="image"
src="https://github.com/user-attachments/assets/5f88797d-c5c3-4c03-9048-c8ee2981c374"
/>
# Checklist for submitter
## Testing
- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
For unreleased bug fixes in a release candidate, one of:
- [x] Confirmed that the fix is not expected to adversely impact load
test results
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Automatic syncing of "Lock end user info" when toggling End User
Authentication now only runs when Apple MDM is enabled and configured
(with an exception when EUA is being disabled to preserve behavior).
* Save payloads omit Apple-only fields unless Apple MDM is configured.
* **UI**
* "Lock end user info" checkbox shows an Apple MDM–gated tooltip and is
disabled when Apple MDM is not configured.
* **Tests**
* Added coverage for Apple MDM–gated behaviors and saved-payload
variations.
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45212)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#42026
- Show "uninstall" button if the status is `installed` (or
`recently_installed`) which just reflects that the install script ran
successfully, not that the software title for the installer is in the
software inventory. For example, even with a no-op install script that
exits successfully the button will be available.
- Make the status clickable by removing the recentlyTakenAction check,
since that only represents the last install script that ran. This should
only really affect the `recently_installed` status (according to claude
at least).
This behaviour is already possible through the API, but it mostly
depends on the specific uninstall scripts if they will pass or fail when
the software doesn't even exist.
# 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.
## Testing
- [x] Added/updated automated tests
- [ ] 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
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Uninstall option now appears for installers even when the host
inventory lacks a matching software entry, ensuring uninstall remains
accessible.
* **Tests**
* Added regression tests verifying the uninstall button is visible and
enabled for relevant installed states, including on personal device
pages.
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45273)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Fixes#43279
On the My device page (DeviceUserPage), the Location and MDM status rows
in the Vitals card rendered as <Button variant="link"> even though no
modal was wired up, so clicking did nothing while the link styling
implied otherwise.
Resolves#39727
Fixed bug on QueryDetailsPage's backPath() implementation, so the "Back
to host details" button does not followed the stale filteredQueriesPath
set when the user previously visited the reports page.
During the confirmation and celebration, we received feedback that the
current copy is confusing.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Clarified timeout/failure messaging for app installs: the modal now
states the install "took longer than {timeout}, so Fleet marked it as
failed," and the follow-up text clarifies the status will update if the
install finishes later.
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45138)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Add OpenVPN Connect to maintained apps: create a Homebrew input manifest
and add an apps.json entry. Add a darwin output with version 3.8.1
(installer URL, sha256) plus install/uninstall script refs that handle
quitting/relaunching and cleanup. Add frontend icon component and
register it in the icon map, and include the app icon asset. Default
category set to Productivity.
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#43646
<img width="809" height="149" alt="image"
src="https://github.com/user-attachments/assets/cf7b55ae-4d79-4686-a9e5-e9e68e4b2e65"
/>
<img width="851" height="190" alt="image"
src="https://github.com/user-attachments/assets/0c70a2b6-091c-4222-b9a9-c4d46f9b0f5b"
/>
# 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.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops
- [x] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
## Testing
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed alignment inconsistency for premium feature messages in Fleet
settings. Premium notifications across Disk Encryption and Passwords
controls now display with proper alignment on Fleet Free tier.
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45125)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
- Also add /learn-more link so we can update the link w/o a Fleet
release
Hosts online:
<img width="494" height="171" alt="Screenshot 2026-05-08 at 5 11 23 PM"
src="https://github.com/user-attachments/assets/98e355d0-2253-426b-851b-494f40ed6e31"
/>
Vulnerability exposure:
<img width="569" height="191" alt="Screenshot 2026-05-08 at 5 11 18 PM"
src="https://github.com/user-attachments/assets/c4d4a026-e365-4321-b79c-6e83581857cc"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a new learning resource link for vulnerability exposure (CVE)
dataset information.
* **Style**
* Updated tooltip link formatting and styling for improved presentation.
* Minor formatting adjustments to dataset descriptions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves
https://github.com/fleetdm/fleet/issues/44949.
- [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.
## Testing
- [X] Added/updated automated tests
- [X] QA'd all new/changed functionality manually
For unreleased bug fixes in a release candidate, one of:
- [X] Confirmed that the fix is not expected to adversely impact load
test results.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Policy retrieval now correctly enforces team authorization, preventing
unauthorized cross-team access and ensuring team policies are returned
properly.
* **New Features**
* UI uses a unified policy access path for viewing/editing policies,
improving consistency for inherited/team-scoped policies,
back-navigation, and fleet-name display (All fleets / No team).
* **Tests**
* Added unit and integration tests covering cross-team access rules and
that policy automation fields are populated when policies are returned.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#44818
## Summary
- Show tier-specific description on the Variables page: Premium users
see "Manage custom variables that will be available in scripts and
profiles across all fleets." while Free users see "Manage custom
variables that will be available in scripts and profiles."
- Uses existing `isPremiumTier` from `AppContext`, consistent with the
rest of the ManageControlsPage components.
## Changes
- `frontend/pages/ManageControlsPage/Variables/Variables.tsx`: Added
`isPremiumTier` to the `AppContext` destructuring and conditionally
render the description text based on tier.
---
Built for [Rachael
Shaw](https://fleetdm.slack.com/archives/D0AFC5BRFHD/p1778192832326539?thread_ts=1777406096.224979&cid=D0AFC5BRFHD)
by [Kilo for Slack](https://kilo.ai/slack)
---------
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
Co-authored-by: Rachael Shaw <r@rachael.wtf>
## Summary
- Updates the "GitOps mode" indicator in the top navigation bar to
become a clickable link that navigates to
`/settings/integrations/change-management` when the current user is a
global admin.
- For non-global-admin users, the indicator remains as a non-clickable
text badge (unchanged behavior).
## Changes
- **`frontend/components/top_nav/SiteTopNav/SiteTopNav.tsx`**: Added
`isGlobalAdmin` prop to `GitOpsModeIndicator` component. When true,
wraps the indicator content in a `<Link>` to
`PATHS.ADMIN_INTEGRATIONS_CHANGE_MANAGEMENT`. Otherwise, renders the
content as-is.
- **`frontend/components/top_nav/SiteTopNav/_styles.scss`**: Added
`.gitops-mode-indicator__link` styles to ensure the link has no default
link styling (no underline, inherited color) and shows a pointer cursor.
Built for [Rachael
Shaw](https://fleetdm.slack.com/archives/D0AFC5BRFHD/p1777410934139609?thread_ts=1777406096.224979&cid=D0AFC5BRFHD)
by [Kilo for Slack](https://kilo.ai/features/slack-integration)
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#44958
# Details
Fixes two issues on the checkerboard:
1. Ensures that the chart shows data going back 30 calendar days (not
720 hours) if it has it
2. Leaves `0` values out of the chart color band calculations in
"relative" color mode
# 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](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
n/a, unreleased
## Testing
- [X] Added/updated automated tests
- [X] QA'd all new/changed functionality manually
**Before**
Colors clustered in top 3 levels, empty boxes in first column:
<img width="705" height="416" alt="image"
src="https://github.com/user-attachments/assets/b867a1a9-4c52-4b96-92fd-04e7848c6295"
/>
**After**
Colors spread over all levels, no empty boxes in first column:
<img width="707" height="412" alt="image"
src="https://github.com/user-attachments/assets/c67e11c5-6dd8-4e66-9c32-9d9213ccb24f"
/>
For unreleased bug fixes in a release candidate, one of:
- [X] Confirmed that the fix is not expected to adversely impact load
test results
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Charts request an extra day to ensure full calendar-day coverage
across timezones.
* Checkerboard visualization excludes empty/no-data slots from relative
color scaling so color ramps reflect non-zero data.
* Calendar view trims leading partial days so the displayed window
matches the selected range.
* **New Features**
* Chart date-range selection expanded to support any value from 1–31
days.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#41472
-
[Figma](https://www.figma.com/design/2jRQoXofC1caxyNhWl8F0m/Android-certificates--support-for-subject-alternative-name--SAN--attributes-in-certificates?node-id=2-130&p=f&m=dev)
- Needs to merge to main after
https://github.com/fleetdm/fleet/pull/44690
# Checklist for submitter
- [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] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added Subject Alternative Name (SAN) field to the certificate
management modal with comprehensive validation support.
* **Tests**
* Expanded test coverage for the certificate modal with enhanced
validation scenarios and server response handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Resolves#34103
The SSO invite acceptance page submitted a create-user request without
the invitee's email, because it read `email` from the URL query string
which the invite email link never populates. To resolve this the email
was loaded by calling GET /api/_version_/fleet/invites/{token} endpoint.
As part of this fix, the ConfirmSSOInvite components were refactored
from 'classical' components to functional components.
Relates to: https://github.com/fleetdm/fleet/issues/44529
## Summary
- Adds "Fleet will try again." text to the host-level activity feed for
MDM commands with a "NotNow" status, matching the existing behavior in
the CommandDetailsModal.
- Previously, users had to open the modal to see this retry information;
now it's visible directly in the activity feed.
## Changes
-
`frontend/pages/hosts/details/cards/Activity/CommandItem/CommandItem.tsx`:
When a command's `status` is `"NotNow"`, append " Fleet will try again."
to the activity text displayed in the feed.
## QA
1. Navigate to a host details page with MDM commands enabled.
2. Trigger or find a command with "NotNow" status (host locked or
running on battery in Power Nap).
3. Verify the activity feed item shows "The **{command}** command is
deferred. Fleet will try again."
4. Verify the CommandDetailsModal still shows the full deferred message
with "Fleet will try again."
---
Built for [Mel
Pike](https://fleetdm.slack.com/archives/D0AKX7DJFCN/p1777575458215749?thread_ts=1777299502.461149&cid=D0AKX7DJFCN)
by [Kilo for Slack](https://kilo.ai/slack)
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
Co-authored-by: melpike <79950145+melpike@users.noreply.github.com>
Resolves#34104
When saving SMTP settings with SSL/TLS off, STARTTLS on, and SSL cert
verification on, the test-email send produced an opaque Go cert error
that gave users no actionable hint. The two TLS-related toggles also
live on different settings cards with no cross-reference, which made the
conflict hard to spot before hitting Save.
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#44676
# 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](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
n/a, unreleased
## Testing
- [ ] Added/updated automated tests
just style fixes, but the ["disable features: frontend"
PR](https://github.com/fleetdm/fleet/pull/44797) has some tests
- [X] QA'd all new/changed functionality manually
- [x] make hosts enrolled chart match height w/ checkerboard
- [x] use empty boxes with outline instead of filled boxes for 0 value
- [x] use dark-mode colors for green theme
- [x] put host enrolled chart bars between horizontal rules instead of
on top of them
- [x] only show date and # of hosts in tooltip, no percentage or
denominator
- [X] add day of week to checkerboard tooltip
- [x] use comma in tooltip numbers
- [x] use relative shading in both datasets
- [x] make text size match between hosts enrolled and checkerboard
titles
- [x] on vuln chart tooltip, add "Want more control over this chart?
Comprehensive vulnerability filtering is [coming soon](link to this
issue: https://github.com/fleetdm/fleet/issues/44746)."
- [x] on vuln chart tooltip, fix link styling in dark mode
- [x] change "Hosts active" => "Hosts online"
- [x] Update tooltip copy to "The number of hosts detected online during
a given hour. A host is considered online if it's actively checking in
to Fleet. This includes sleeping hosts (e.g. lid closed)."
- [X] Fix issue where at smaller widths, the entire page has a
horizontal scrollbar
- [X] Make charts stay pegged to the right side when first loaded and
when resizing window
Charts align:
<img width="1223" height="479" alt="image"
src="https://github.com/user-attachments/assets/4a7ba859-a0aa-43c6-a06b-4ef8361e2418"
/>
Data tooltip:
<img width="162" height="77" alt="image"
src="https://github.com/user-attachments/assets/5b1768e4-0736-4e45-ad49-6faf31958352"
/>
Vuln tooltip:
<img width="387" height="123" alt="image"
src="https://github.com/user-attachments/assets/98c2096f-fa4e-4b06-917e-ec6eed844b05"
/>
Hosts online tooltip:
<img width="360" height="113" alt="image"
src="https://github.com/user-attachments/assets/bd65cd1d-0f0c-4c72-a31d-ffe602cacd9c"
/>
For unreleased bug fixes in a release candidate, one of:
- [X] Confirmed that the fix is not expected to adversely impact load
test results
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Optional relative scaling for chart visualizations
* Responsive chart sizing in the Hosts Enrolled card
* **Improvements**
* Dataset label updated to "Hosts online"
* Tooltips and labels show formatted host counts with proper
pluralization
* Day labels now include weekday for clearer dates
* Chart descriptions mention upcoming vulnerability filtering
* Tighter header, dropdown, scrollbar, and dark‑mode styling
* **Tests**
* Updated dataset heading test and added a relative‑scale color ramp
test
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Rachael Shaw <r@rachael.wtf>
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
Co-authored-by: Luke Heath <luke@fleetdm.com>