Fleet UI: Self service page > Custom categories - #46566
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## feat/39018-self-service-categories #46566 +/- ##
=====================================================================
Coverage ? 66.88%
=====================================================================
Files ? 2812
Lines ? 223940
Branches ? 11431
=====================================================================
Hits ? 149783
Misses ? 60603
Partials ? 13554
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Introduces the CategoryFilter dropdown for the self-service software page, with a sticky in-menu search input. Includes the ISelfServiceCategory interface and self_service_categories service entity used by the component.
Adds the InstallAllInCategoryButton component and confirmation modal,
the DEVICE_SOFTWARE_INSTALL_ALL endpoint, and the
installAllSelfServiceSoftwareInCategory service method. Posts to
/device/{token}/software/install_all with an optional category_id.
Replaces the static category sidebar on the My device > Self-service page with a custom-category dropdown driven by the org's self-service categories. Adds the SELF_SERVICE_CATEGORIES endpoints and MSW handlers to mock the backend while it lands.
- Replace react-select control with a Fleet <Button variant="unstyled"> trigger so the dropdown gets the standard :focus-visible outline on Tab (and nothing on mouse click) - Animate chevron on open/close via __icon / __icon--open modifier; move CustomDropdownIndicator to module scope so react-select doesn't unmount it mid-transition - Keep react-select's hidden Control rendered (out of Tab order) so ArrowDown/Up/Enter/Escape forward from the in-menu search input via dispatched KeyboardEvent - Auto-focus the in-menu search input on open; stop mousedown propagation on the input and MenuList padding so react-select's onMenuMouseDown doesn't steal focus and close the menu - Cap trigger label and option rows at max-width 350px with ellipsis; menu max-width 350px so very long custom category names can't blow out the layout
- Type onClickInstallAction properly (was `any`) and make it required - Add fleet arg to the categories queryKey to prevent cache bleed - filterSoftwareByCustomCategory returns [] when categoryId is stale - Case-insensitive category name match against software's categories enum - Drop deprecated keyCode/which from forwarded keydown events - Auto-clear stale category_id from URL when categories load empty - Hide the category dropdown entirely when org has no categories - Exclude recently_uninstalled and failed_uninstall* from install_all count - Close install-all modal before firing the success callback - Drop the "All pinned" filter and let the no-match message render - Fixed dropdown width to 340px; empty-state height matches an option row - Delete dead filterSoftwareByCategory; @deprecate stale category constants - Style polish: remove redundant transition + transform: rotate(0deg) - Tests: CategoryFilter.tests.tsx (new), install-all confirm flow, hidden-dropdown state, stale-URL recovery, realistic per_page fixture - Replace brittle hardcoded react-select-N-listbox id lookup with aria-controls
…derive isEmptySearch locally (#39018) - Exclude `ran_script` from install_all eligibility (already-run scripts shouldn't re-run); `never_ran_script` stays eligible so first-time script runs are queued - Replace inventory-shaped EmptySoftwareTable fallback in SelfServiceTable with self-service-appropriate copy - Derive `isEmptySearch` inside SelfServiceTable from `queryParams.query` instead of threading a drift-prone prop from SelfService.tsx (which was computed against the API response, not the filtered list); drop the prop from SelfServiceCard and SelfService.tsx
…onents (#39018) - helpers.tests.ts: 24 tests; one per status exclusion in INSTALLED_OR_IN_FLIGHT_UI_STATUSES so future edits don't silently drop recently_uninstalled, failed_uninstall_*, ran_script, etc. Also covers filterSoftwareByCustomCategory's stale-URL and case-insensitive paths - InstallAllInCategoryButton.tests.tsx: render states, modal confirm flow (POSTs with/without category_id), cancel-without-POST, error path keeps modal open and doesn't fire onSuccess - InstallAllInCategoryModal.tests.tsx: title + confirm/cancel handlers, singular/plural copy, disabled-while-submitting - SelfServiceFilters.tests.tsx: CategoryFilter gate (hidden when categories empty), install-all slot rendering
f86f8c1 to
83681fd
Compare
Replaces the left-side CategoriesMenu in SelfServicePreview with a static "All" dropdown above the table, threads teamId through both preview modal callsites so categories are fetched per fleet, and adds an Install status column to the preview table. Removes the now-unused CategoriesMenu component and CATEGORIES_NAV_ITEMS export.
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 |
…-id recovery (#39018) - Wire SelfServiceCard to GET /device/{token}/software/self_service_categories so categories scope by the host's fleet via the device token, instead of the hardcoded fleet_id=0 stand-in. Adds the endpoint constant, API method, and matching MSW handlers. - Widen the auto-clear effect to also drop category_id when it's not in the loaded categories list (previously only fired on empty list), preventing the "trigger says All, table empty" state when a bookmarked id has been deleted. - Remove a duplicate :has() rule in CategoriesEndUserExperienceModal styles.
… renders (#39018) Restructures SelfServiceFilters into flat siblings (CategoryFilter, __install-all, __search) and adds a --with-categories modifier on the filter row. Under $break-sm, that modifier scopes a media query that sends __search to its own full-width top row, leaving CategoryFilter (left) and Install all (right) on row 2. Without categories the row stays single-line at any width.
|
TODO: Ensure success/error messages are what we want (missing in specs) |
1036719
into
feat/39018-self-service-categories
Issue
Part of #39018
Closes
Description
Screenrecording
Testing