diff --git a/changes/my-device-applications-filter b/changes/my-device-applications-filter new file mode 100644 index 0000000000..3cc0812368 --- /dev/null +++ b/changes/my-device-applications-filter @@ -0,0 +1 @@ +- Added the "Applications" / "Full inventory" software filter to the Fleet Desktop **My device > Software** tab for macOS hosts, matching the host details page. diff --git a/frontend/pages/hosts/details/cards/Software/HostSoftware.tsx b/frontend/pages/hosts/details/cards/Software/HostSoftware.tsx index 41efc77154..69e1e1ba9a 100644 --- a/frontend/pages/hosts/details/cards/Software/HostSoftware.tsx +++ b/frontend/pages/hosts/details/cards/Software/HostSoftware.tsx @@ -162,16 +162,13 @@ const HostSoftware = ({ ? isPremiumTierProp : isPremiumTierFromContext; - // The /Applications filter only applies to macOS hosts on the host details - // page, and defaults to ON (only top-level applications) when the host is - // macOS and no explicit value is set in the URL. It is left undefined for - // other platforms, and on the My device page (which has no filter dropdown), - // so the param is neither sent to the API nor appended to the URL on - // pagination. - const macosApplicationsFilter = - !isMyDevicePage && isMacOS(platform) - ? queryParams.macos_applications ?? true - : undefined; + // The /Applications filter only applies to macOS hosts, and defaults to ON + // (only top-level applications) when the host is macOS and no explicit value + // is set in the URL. It is left undefined for other platforms, so the param + // is neither sent to the API nor appended to the URL on pagination. + const macosApplicationsFilter = isMacOS(platform) + ? queryParams.macos_applications ?? true + : undefined; const isUnsupported = isIPadOrIPhone(platform) && queryParams.vulnerable; // no Android software and no vulnerable software for iOS @@ -227,6 +224,7 @@ const HostSoftware = ({ id: id as string, softwareUpdatedAt, ...queryParams, + macos_applications: macosApplicationsFilter, }, ], ({ queryKey }) => deviceAPI.getDeviceSoftware(queryKey[0]), diff --git a/frontend/pages/hosts/details/cards/Software/HostSoftwareTable/HostSoftwareTable.tests.tsx b/frontend/pages/hosts/details/cards/Software/HostSoftwareTable/HostSoftwareTable.tests.tsx index a359d600f4..5005183ca7 100644 --- a/frontend/pages/hosts/details/cards/Software/HostSoftwareTable/HostSoftwareTable.tests.tsx +++ b/frontend/pages/hosts/details/cards/Software/HostSoftwareTable/HostSoftwareTable.tests.tsx @@ -155,6 +155,16 @@ describe("HostSoftwareTable", () => { expect(screen.queryByText("Full inventory")).not.toBeInTheDocument(); }); + it("renders the /Applications filter on the My device page for macOS hosts", () => { + renderWithContext({ + platform: "darwin", + macosApplicationsFilter: true, + isMyDevicePage: true, + }); + + expect(screen.getByText("Applications")).toBeInTheDocument(); + }); + it("appends macos_applications to the URL on pagination when the filter is set", () => { const router = createMockRouter(); renderWithContext({ @@ -171,19 +181,35 @@ describe("HostSoftwareTable", () => { ); }); - it("does not append macos_applications to the URL on pagination when the filter is undefined (My device page)", () => { + it("appends macos_applications to the URL on pagination on the My device page", () => { const router = createMockRouter(); renderWithContext({ router, platform: "darwin", - // My device page leaves the filter undefined since it has no dropdown. - macosApplicationsFilter: undefined, + macosApplicationsFilter: true, isMyDevicePage: true, data: fullPageWithNextResults, }); fireEvent.click(screen.getByRole("button", { name: /next/i })); + expect(router.replace).toHaveBeenCalledWith( + expect.stringContaining("macos_applications=true") + ); + }); + + it("does not append macos_applications to the URL on pagination when the filter is undefined (non-macOS host)", () => { + const router = createMockRouter(); + renderWithContext({ + router, + platform: "windows", + // Non-macOS platforms leave the filter undefined since it doesn't apply. + macosApplicationsFilter: undefined, + data: fullPageWithNextResults, + }); + + fireEvent.click(screen.getByRole("button", { name: /next/i })); + expect(router.replace).toHaveBeenCalledTimes(1); expect(router.replace).not.toHaveBeenCalledWith( expect.stringContaining("macos_applications") diff --git a/frontend/pages/hosts/details/cards/Software/HostSoftwareTable/HostSoftwareTable.tsx b/frontend/pages/hosts/details/cards/Software/HostSoftwareTable/HostSoftwareTable.tsx index ce41f43762..15be2ce39c 100644 --- a/frontend/pages/hosts/details/cards/Software/HostSoftwareTable/HostSoftwareTable.tsx +++ b/frontend/pages/hosts/details/cards/Software/HostSoftwareTable/HostSoftwareTable.tsx @@ -217,9 +217,7 @@ const HostSoftwareTable = ({ // The /Applications filter is only relevant for macOS hosts. const showApplicationsFilter = - !isMyDevicePage && - isMacOS(platform) && - macosApplicationsFilter !== undefined; + isMacOS(platform) && macosApplicationsFilter !== undefined; const applicationsFilterOptions: CustomOptionType[] = [ { label: "Full inventory", value: "false" },