Add macOS app filter to My device software (#48637)
Expose the existing "Applications" / "Full inventory" software filter on the Fleet Desktop My device Software tab for macOS hosts. The filter now defaults to Applications for macOS, sends `macos_applications` to the device software API, and keeps that query param during pagination. Updated table tests cover rendering and URL behavior on My device and non-macOS hosts. <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #48636 # 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. - [ ] Timeouts are implemented and retries are limited to avoid infinite loops - [ ] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [ ] 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) - [ ] QA'd all new/changed functionality manually For unreleased bug fixes in a release candidate, one of: - [ ] Confirmed that the fix is not expected to adversely impact load test results - [ ] Alerted the release DRI if additional load testing is needed ## Database migrations - [ ] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [ ] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [ ] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). ## New Fleet configuration settings - [ ] Setting(s) is/are explicitly excluded from GitOps If you didn't check the box above, follow this checklist for GitOps-enabled settings: - [ ] Verified that the setting is exported via `fleetctl generate-gitops` - [ ] Verified the setting is documented in a separate PR to [the GitOps documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485) - [ ] Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional) - [ ] Verified that any relevant UI is disabled when GitOps mode is enabled ## fleetd/orbit/Fleet Desktop - [ ] Verified compatibility with the latest released version of Fleet (see [Must rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/workflows/fleetd-development-and-release-strategy.md)) - [ ] If the change applies to only one platform, confirmed that `runtime.GOOS` is used as needed to isolate changes - [ ] Verified that fleetd runs on macOS, Linux and Windows - [ ] Verified auto-update works from the released version of component to the new version (see [tools/tuf/test](../tools/tuf/test/README.md)) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added the **Applications / Full inventory** software filter to the **My device > Software** tab for macOS devices. * The selected filter is now preserved when navigating through software results. * **Bug Fixes** * Corrected software filtering behavior across device pages and platforms. * Prevented the macOS filter parameter from being added for non-macOS devices. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -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.
|
||||
@@ -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]),
|
||||
|
||||
+29
-3
@@ -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")
|
||||
|
||||
@@ -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" },
|
||||
|
||||
Reference in New Issue
Block a user