Fleet UI: Fix export button dependencies#45020
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #45020 +/- ##
========================================
Coverage 66.77% 66.77%
========================================
Files 2718 2718
Lines 218817 218816 -1
Branches 10748 10624 -124
========================================
+ Hits 146123 146124 +1
+ Misses 59532 59529 -3
- Partials 13162 13163 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@claude review |
There was a problem hiding this comment.
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.
|
@claude review |
There was a problem hiding this comment.
Pull request overview
Fixes a stale-closure bug on the Manage Hosts page where the “Export hosts” button could export using outdated sort/search/filter state by ensuring the export click handler is properly memoized and referenced.
Changes:
- Memoized
onExportHostsResultswithuseCallbackand added the relevant dependency list so it always captures current table state. - Updated the count renderer callback (
renderHostCountAndExport) to depend ononExportHostsResults, preventing stale export handlers. - Added a changes entry describing the user-visible fix.
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx | Memoizes export handler and updates callback dependencies so exports reflect current UI state. |
| changes/45018-export-host-bug | Adds changelog entry for the export button fix. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| isOnlyObserver, | ||
| const columnIds = tableColumns | ||
| .map((column) => (column.id ? column.id : "")) | ||
| // "selection" colum does not include any relevent data for the CSV |
| renderFlash("error", "Could not export hosts. Please try again."); | ||
| } | ||
| }; | ||
| queryParams.fleet_id, |
| @@ -0,0 +1 @@ | |||
| - Fleet UI: Export hosts button now always reflects the current sort, search, and filter state instead of potentially using stale values. | |||
|
ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughThe PR refactors the ManageHostsPage export flow: it memoizes the export handler into onExportHostsResults (computing visibleColumns, building a full hostsAPI.exportHosts options payload including queryParams.fleet_id handling), introduces renderHostCountAndExport to render the count plus the Export button wired to the memoized handler, and wires that callback into TableContainer via its renderCount prop so exports reflect current sort/search/filter state. Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx (1)
1567-1685:⚠️ Potential issue | 🟠 Major | ⚡ Quick winExport uses stale
localStoragefor hidden columns, ignoring server-persisted user settingsLines 1571–1592 read hidden columns from
localStorage.getItem("hostHiddenColumns"). The migration block at lines 641–662 removes that key after successfully syncing to the server (localStorage.removeItem("hostHiddenColumns")). For any user who has been migrated, this read returnsnull, socurrentHiddenColumnsstays[]andgenerateVisibleTableColumnsis called withhiddenColumns: []— treating every column as visible regardless of the user's actual preferences. The exported CSV will include all columns instead of only the ones the user has enabled.The
hiddenColumnsstate variable is already the correct source of truth (initialized fromuserSettings?.hidden_host_columnsand kept in sync byonSaveColumns). It should be used directly, and added to the dependency array.🐛 Proposed fix
- const hiddenColumnsStorage = localStorage.getItem("hostHiddenColumns"); - let currentHiddenColumns = []; - let visibleColumns; - if (hiddenColumnsStorage) { - currentHiddenColumns = JSON.parse(hiddenColumnsStorage); - } + let visibleColumns; if (config && currentUser) { const tableColumns = generateVisibleTableColumns({ - hiddenColumns: currentHiddenColumns, + hiddenColumns, isFreeTier, isOnlyObserver, teamId: teamIdForApi, });Add
hiddenColumnsto the dependency array:}, [ config, currentUser, + hiddenColumns, isFreeTier, isOnlyObserver, teamIdForApi, // ... rest of deps unchanged ]);🤖 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 `@frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx` around lines 1567 - 1685, The export handler onExportHostsResults incorrectly reads hidden columns from localStorage ("hostHiddenColumns") causing migrated users to get stale [] instead of their server-synced settings; instead, use the component state hiddenColumns (which is initialized from userSettings?.hidden_host_columns and updated by onSaveColumns) when calling generateVisibleTableColumns and remove the localStorage.getItem fallback logic, and add hiddenColumns to the useCallback dependency array so exports reflect current column visibility.
🤖 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.
Outside diff comments:
In `@frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx`:
- Around line 1567-1685: The export handler onExportHostsResults incorrectly
reads hidden columns from localStorage ("hostHiddenColumns") causing migrated
users to get stale [] instead of their server-synced settings; instead, use the
component state hiddenColumns (which is initialized from
userSettings?.hidden_host_columns and updated by onSaveColumns) when calling
generateVisibleTableColumns and remove the localStorage.getItem fallback logic,
and add hiddenColumns to the useCallback dependency array so exports reflect
current column visibility.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: afb39255-e8bb-44d8-83cb-9153cbbeafc5
📒 Files selected for processing (2)
changes/45018-export-host-bugfrontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx
|
@claude review |
There was a problem hiding this comment.
All three issues from my prior review have been addressed: hidden-columns now uses the in-memory state, the missing filter keys are included in the export options, and the unused dep was dropped.
Extended reasoning...
Overview
This PR fixes a stale-closure bug in the Hosts page Export button by wrapping onExportHostsResults in useCallback with a complete dependency list, and combining it with the host count renderer into renderHostCountAndExport. The two changed files are a one-line changelog entry and frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx.
Security risks
None. This is a pure UI change. The export call already routed through hostsAPI.exportHosts with the same set of filter parameters used elsewhere on the page; the change just ensures those parameters reflect current state. No auth, crypto, permission, or data-boundary code is touched.
Level of scrutiny
Low-to-medium. Frontend bug fix scoped to a single page component, no API or backend changes. The author also incorporated additional findings from my earlier review (using the hiddenColumns state instead of the post-migration-empty localStorage value, and adding diskEncryptionStatus, depProfileError, depAssignProfileResponse to the export options) and produced a screenshot confirming the columns behavior is correct.
Other factors
Remaining nits are minor: pre-existing typos in a moved comment (colum/relevent), an unguarded queryParams.fleet_id access in the dep list (consistent with how the page already uses queryParams elsewhere), and bullet style in the changes file. None warrant blocking. QA was performed manually with a screen recording attached.
Issue
Closes #45018
Description
Reviewer note
Hide whitespace for easier time reviewing diff
Screen recording of fix
https://fleetdm.zoom.us/clips/share/zUs8dkogS2mi7FvjIEGvIA
Checklist for submitter
If some of the following don't apply, delete the relevant line.
changes/,orbit/changes/oree/fleetd-chrome/changes.See Changes files for more information.
Testing
Summary by CodeRabbit