Add "update new hosts to latest" to OS Updates form for MacOS (#37103)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #36088 # 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 - [X] QA'd all new/changed functionality manually Saving this value currently results in a 400 response from the server since it's not a valid key yet. We can keep this in draft until the backend is merged if we want to e2e test with it. ### Controls -> OS Settings "Target" section #### All platforms - [X] Update success banner message to "Successfully updated." <img width="200" alt="image" src="https://github.com/user-attachments/assets/bc43ec79-41d1-4dd3-947c-8152051fd209" /> #### macOS / iOS / iPadOS - [X] Update tooltip text for "Minimum version" to `Enrolled hosts are updated to exactly this version.` <img width="250" alt="Image" src="https://github.com/user-attachments/assets/7d870224-395e-4bc9-937e-be599da57a97" /> - [X] Make "available from Apple" a link, replacing "Learn more", and link to https://fleetdm.com/learn-more-about/apple-available-os-updates <img width="250" height="363" alt="image" src="https://github.com/user-attachments/assets/8191ec2d-bf0a-4cf6-9b1a-1272c0ff69b0" /> > Note - this URL is current a 404 - [X] Remove text referring to platform from "End user experience" heading, i.e. it should just say "End user experience" for all platforms where it appears, not e.g. "End user experience on macOS" #### macOS Only - [X] Add new "Update new hosts to latest" checkbox <img width="316" height="406" alt="Image" src="https://github.com/user-attachments/assets/71aec05a-b809-436d-8bfd-cd3e14b27ea1" /> - [X] Reflects the `macos_updates.update_new_hosts` setting for the team or (for no team) global config (only testable via automated tests right now) - [X] Update End user experience text to "When a minimum version is enforced, end users see a native macOS notification (DDM) once per day." (see above) ### Global activity feed - [X] When "Update new hosts to latest" is enabled, activity should say `[Actor's name] enabled OS updates for all new macOS hosts on the [team name] team. macOS hosts will upgrade to the lastest version when they enroll.` - [X] When "Update new hosts to latest" is disabled, activity should say `[Actor's name] disabled updates for all new macOS hosts on the [team name] team.` (tested via automated tests)
This commit is contained in:
@@ -0,0 +1 @@
|
||||
- Added ability to indicate that new MacOS hosts enrolling via ADE should be updated to the latest operating system version.
|
||||
@@ -43,6 +43,8 @@ export enum ActivityType {
|
||||
EditedMacosMinVersion = "edited_macos_min_version",
|
||||
EditedIosMinVersion = "edited_ios_min_version",
|
||||
EditedIpadosMinVersion = "edited_ipados_min_version",
|
||||
EnabledMacosUpdateNewHosts = "enabled_macos_update_new_hosts",
|
||||
DisabledMacosUpdateNewHosts = "disabled_macos_update_new_hosts",
|
||||
ReadHostDiskEncryptionKey = "read_host_disk_encryption_key",
|
||||
/** Note: BE not renamed (yet) from macOS even though activity is also used for iOS and iPadOS */
|
||||
CreatedAppleOSProfile = "created_macos_profile",
|
||||
@@ -326,6 +328,7 @@ export const ACTIVITY_DISPLAY_NAME_MAP: Record<ActivityType, string> = {
|
||||
disabled_macos_disk_encryption: "Turned off disk encryption",
|
||||
disabled_macos_setup_end_user_auth:
|
||||
"Turned off end user authentication (setup experience)",
|
||||
disabled_macos_update_new_hosts: "Disabled OS updates for new macOS hosts",
|
||||
disabled_vpp: "Disabled Volume Purchasing Program (VPP)",
|
||||
disabled_windows_mdm: "Turned off Windows MDM",
|
||||
disabled_windows_mdm_migration: "Turned off Windows MDM migration",
|
||||
@@ -357,6 +360,7 @@ export const ACTIVITY_DISPLAY_NAME_MAP: Record<ActivityType, string> = {
|
||||
enabled_macos_disk_encryption: "Turned on disk encryption",
|
||||
enabled_macos_setup_end_user_auth:
|
||||
"Turned on end user authentication (setup experience)",
|
||||
enabled_macos_update_new_hosts: "Enabled OS updates for new macOS hosts",
|
||||
enabled_vpp: "Enabled Volume Purchasing Program (VPP)",
|
||||
enabled_windows_mdm: "Turned on Windows MDM",
|
||||
enabled_windows_mdm_migration: "Turned on Windows MDM migration",
|
||||
|
||||
@@ -41,6 +41,7 @@ interface ICustomSetting {
|
||||
export interface IAppleDeviceUpdates {
|
||||
minimum_version: string;
|
||||
deadline: string;
|
||||
update_new_hosts?: boolean;
|
||||
}
|
||||
|
||||
export interface IMdmConfig {
|
||||
|
||||
+32
@@ -1734,4 +1734,36 @@ describe("Activity Feed", () => {
|
||||
expect(screen.getByText(/Bears/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/team/i)).toBeInTheDocument();
|
||||
});
|
||||
it("renders an enabledMacosUpdateNewHosts activity for a team", () => {
|
||||
const activity = createMockActivity({
|
||||
type: ActivityType.EnabledMacosUpdateNewHosts,
|
||||
details: {
|
||||
team_name: "Lions",
|
||||
team_id: 1,
|
||||
},
|
||||
});
|
||||
render(<GlobalActivityItem activity={activity} isPremiumTier />);
|
||||
expect(
|
||||
screen.getByText(/enabled OS updates for all new/i)
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText(/macOS/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/Lions/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/team/i)).toBeInTheDocument();
|
||||
});
|
||||
it("renders a disabledMacosUpdateNewHosts activity for a team", () => {
|
||||
const activity = createMockActivity({
|
||||
type: ActivityType.DisabledMacosUpdateNewHosts,
|
||||
details: {
|
||||
team_name: "Lions",
|
||||
team_id: 1,
|
||||
},
|
||||
});
|
||||
render(<GlobalActivityItem activity={activity} isPremiumTier />);
|
||||
expect(
|
||||
screen.getByText(/disabled updates for all new/i)
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText(/macOS/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/Lions/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/team/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
+46
@@ -435,6 +435,46 @@ const TAGGED_TEMPLATES = {
|
||||
);
|
||||
},
|
||||
|
||||
enabledAppleosUpdateNewHosts: (
|
||||
applePlatform: AppleDisplayPlatform,
|
||||
activity: IActivity
|
||||
) => {
|
||||
const teamSection = activity.details?.team_id ? (
|
||||
<>
|
||||
the <b>{activity.details.team_name}</b> team
|
||||
</>
|
||||
) : (
|
||||
<>no team</>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
enabled OS updates for all new {applePlatform} hosts on {teamSection}.
|
||||
{applePlatform} hosts will upgrade to the lastest version when they
|
||||
enroll.
|
||||
</>
|
||||
);
|
||||
},
|
||||
|
||||
disabledAppleosUpdateNewHosts: (
|
||||
applePlatform: AppleDisplayPlatform,
|
||||
activity: IActivity
|
||||
) => {
|
||||
const teamSection = activity.details?.team_id ? (
|
||||
<>
|
||||
the <b>{activity.details.team_name}</b> team
|
||||
</>
|
||||
) : (
|
||||
<>no team</>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
disabled updates for all new {applePlatform} hosts on {teamSection}.
|
||||
</>
|
||||
);
|
||||
},
|
||||
|
||||
readHostDiskEncryptionKey: (activity: IActivity) => {
|
||||
return (
|
||||
<>
|
||||
@@ -1691,6 +1731,12 @@ const getDetail = (activity: IActivity, isPremiumTier: boolean) => {
|
||||
case ActivityType.EditedIpadosMinVersion: {
|
||||
return TAGGED_TEMPLATES.editedAppleosMinVersion("iPadOS", activity);
|
||||
}
|
||||
case ActivityType.EnabledMacosUpdateNewHosts: {
|
||||
return TAGGED_TEMPLATES.enabledAppleosUpdateNewHosts("macOS", activity);
|
||||
}
|
||||
case ActivityType.DisabledMacosUpdateNewHosts: {
|
||||
return TAGGED_TEMPLATES.disabledAppleosUpdateNewHosts("macOS", activity);
|
||||
}
|
||||
case ActivityType.ReadHostDiskEncryptionKey: {
|
||||
return TAGGED_TEMPLATES.readHostDiskEncryptionKey(activity);
|
||||
}
|
||||
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
import React from "react";
|
||||
import { render, screen, waitFor } from "@testing-library/react";
|
||||
|
||||
import { createCustomRenderer } from "test/test-utils";
|
||||
|
||||
import { http, HttpResponse } from "msw";
|
||||
import mockServer from "test/mock-server";
|
||||
|
||||
import AppleOSTargetForm from "./AppleOSTargetForm";
|
||||
|
||||
const baseUrl = (path: string) => {
|
||||
return `/api/latest/fleet${path}`;
|
||||
};
|
||||
|
||||
describe("AppleOSTargetForm", () => {
|
||||
let requestBody: any;
|
||||
const renderWithBackend = createCustomRenderer({
|
||||
withBackendMock: true,
|
||||
});
|
||||
const updateTeamConfigHandler = http.patch(
|
||||
baseUrl("/teams/1"),
|
||||
async ({ request }) => {
|
||||
requestBody = await request.json();
|
||||
return HttpResponse.json({});
|
||||
}
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
requestBody = undefined;
|
||||
mockServer.use(updateTeamConfigHandler);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mockServer.resetHandlers();
|
||||
});
|
||||
|
||||
it("renders the correct form for MacOS", () => {
|
||||
render(
|
||||
<AppleOSTargetForm
|
||||
currentTeamId={1}
|
||||
applePlatform="darwin"
|
||||
defaultMinOsVersion="11.0"
|
||||
defaultDeadline="2024-12-31"
|
||||
defaultUpdateNewHosts
|
||||
refetchAppConfig={jest.fn()}
|
||||
refetchTeamConfig={jest.fn()}
|
||||
/>
|
||||
);
|
||||
|
||||
const minVersionInput = screen.getByLabelText(/Minimum version/i);
|
||||
expect(minVersionInput).toBeInTheDocument();
|
||||
expect((minVersionInput as HTMLInputElement).value).toBe("11.0");
|
||||
|
||||
const deadlineInput = screen.getByLabelText(/Deadline/i);
|
||||
expect(deadlineInput).toBeInTheDocument();
|
||||
expect((deadlineInput as HTMLInputElement).value).toBe("2024-12-31");
|
||||
|
||||
const updateNewHostsCheckbox = screen.getByLabelText(
|
||||
/Update new hosts to latest/i
|
||||
);
|
||||
expect(updateNewHostsCheckbox).toBeInTheDocument();
|
||||
expect((updateNewHostsCheckbox as HTMLInputElement).checked).toBe(true);
|
||||
});
|
||||
|
||||
it("saves 'update new hosts' checkbox state correctly for macOS", async () => {
|
||||
const { user } = renderWithBackend(
|
||||
<AppleOSTargetForm
|
||||
currentTeamId={1}
|
||||
applePlatform="darwin"
|
||||
defaultMinOsVersion="11.0"
|
||||
defaultDeadline="2024-12-31"
|
||||
defaultUpdateNewHosts
|
||||
refetchAppConfig={jest.fn()}
|
||||
refetchTeamConfig={jest.fn()}
|
||||
/>
|
||||
);
|
||||
const saveButton = screen.getByRole("button", { name: /Save/i });
|
||||
expect(saveButton).toBeInTheDocument();
|
||||
await user.click(saveButton);
|
||||
await waitFor(() => {
|
||||
expect(requestBody).toBeDefined();
|
||||
expect(requestBody?.mdm?.macos_updates?.update_new_hosts).toBe(true);
|
||||
expect(requestBody?.mdm?.macos_updates?.minimum_version).toBe("11.0");
|
||||
expect(requestBody?.mdm?.macos_updates?.deadline).toBe("2024-12-31");
|
||||
});
|
||||
|
||||
const updateNewHostsCheckbox = screen.getByRole("checkbox", {
|
||||
name: /update_new_hosts/i,
|
||||
});
|
||||
await user.click(updateNewHostsCheckbox);
|
||||
await waitFor(() => {
|
||||
expect(updateNewHostsCheckbox).not.toBeChecked();
|
||||
});
|
||||
await user.click(saveButton);
|
||||
await waitFor(() => {
|
||||
expect(requestBody).toBeDefined();
|
||||
expect(requestBody?.mdm?.macos_updates?.update_new_hosts).toBe(false);
|
||||
expect(requestBody?.mdm?.macos_updates?.minimum_version).toBe("11.0");
|
||||
expect(requestBody?.mdm?.macos_updates?.deadline).toBe("2024-12-31");
|
||||
});
|
||||
});
|
||||
|
||||
it("renders the correct form for iOS", () => {
|
||||
render(
|
||||
<AppleOSTargetForm
|
||||
currentTeamId={1}
|
||||
applePlatform="ios"
|
||||
defaultMinOsVersion="11.0"
|
||||
defaultDeadline="2024-12-31"
|
||||
defaultUpdateNewHosts
|
||||
refetchAppConfig={jest.fn()}
|
||||
refetchTeamConfig={jest.fn()}
|
||||
/>
|
||||
);
|
||||
|
||||
const minVersionInput = screen.getByLabelText(/Minimum version/i);
|
||||
expect(minVersionInput).toBeInTheDocument();
|
||||
expect((minVersionInput as HTMLInputElement).value).toBe("11.0");
|
||||
|
||||
const deadlineInput = screen.getByLabelText(/Deadline/i);
|
||||
expect(deadlineInput).toBeInTheDocument();
|
||||
expect((deadlineInput as HTMLInputElement).value).toBe("2024-12-31");
|
||||
|
||||
const updateNewHostsCheckbox = screen.queryByLabelText(
|
||||
/Update new hosts to latest/i
|
||||
);
|
||||
expect(updateNewHostsCheckbox).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("saves 'update new hosts' checkbox state correctly for iOS", async () => {
|
||||
const { user } = renderWithBackend(
|
||||
<AppleOSTargetForm
|
||||
currentTeamId={1}
|
||||
applePlatform="ios"
|
||||
defaultMinOsVersion="12.0"
|
||||
defaultDeadline="2025-12-31"
|
||||
defaultUpdateNewHosts
|
||||
refetchAppConfig={jest.fn()}
|
||||
refetchTeamConfig={jest.fn()}
|
||||
/>
|
||||
);
|
||||
const saveButton = screen.getByRole("button", { name: /Save/i });
|
||||
expect(saveButton).toBeInTheDocument();
|
||||
await user.click(saveButton);
|
||||
await waitFor(() => {
|
||||
expect(requestBody).toBeDefined();
|
||||
expect(requestBody?.mdm?.ios_updates?.update_new_hosts).not.toBeDefined();
|
||||
expect(requestBody?.mdm?.ios_updates?.minimum_version).toBe("12.0");
|
||||
expect(requestBody?.mdm?.ios_updates?.deadline).toBe("2025-12-31");
|
||||
});
|
||||
});
|
||||
|
||||
it("renders the correct form for iPadOS", () => {
|
||||
render(
|
||||
<AppleOSTargetForm
|
||||
currentTeamId={1}
|
||||
applePlatform="ipados"
|
||||
defaultMinOsVersion="11.0"
|
||||
defaultDeadline="2024-12-31"
|
||||
defaultUpdateNewHosts
|
||||
refetchAppConfig={jest.fn()}
|
||||
refetchTeamConfig={jest.fn()}
|
||||
/>
|
||||
);
|
||||
|
||||
const minVersionInput = screen.getByLabelText(/Minimum version/i);
|
||||
expect(minVersionInput).toBeInTheDocument();
|
||||
expect((minVersionInput as HTMLInputElement).value).toBe("11.0");
|
||||
|
||||
const deadlineInput = screen.getByLabelText(/Deadline/i);
|
||||
expect(deadlineInput).toBeInTheDocument();
|
||||
expect((deadlineInput as HTMLInputElement).value).toBe("2024-12-31");
|
||||
|
||||
const updateNewHostsCheckbox = screen.queryByLabelText(
|
||||
/Update new hosts to latest/i
|
||||
);
|
||||
expect(updateNewHostsCheckbox).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("saves 'update new hosts' checkbox state correctly for iPadOS", async () => {
|
||||
const { user } = renderWithBackend(
|
||||
<AppleOSTargetForm
|
||||
currentTeamId={1}
|
||||
applePlatform="ipados"
|
||||
defaultMinOsVersion="13.0"
|
||||
defaultDeadline="2026-12-31"
|
||||
defaultUpdateNewHosts
|
||||
refetchAppConfig={jest.fn()}
|
||||
refetchTeamConfig={jest.fn()}
|
||||
/>
|
||||
);
|
||||
const saveButton = screen.getByRole("button", { name: /Save/i });
|
||||
expect(saveButton).toBeInTheDocument();
|
||||
await user.click(saveButton);
|
||||
await waitFor(() => {
|
||||
expect(requestBody).toBeDefined();
|
||||
expect(
|
||||
requestBody?.mdm?.ipados_updates?.update_new_hosts
|
||||
).not.toBeDefined();
|
||||
expect(requestBody?.mdm?.ipados_updates?.minimum_version).toBe("13.0");
|
||||
expect(requestBody?.mdm?.ipados_updates?.deadline).toBe("2026-12-31");
|
||||
});
|
||||
});
|
||||
});
|
||||
+35
-17
@@ -10,6 +10,7 @@ import { ApplePlatform } from "interfaces/platform";
|
||||
// @ts-ignore
|
||||
import InputField from "components/forms/fields/InputField";
|
||||
import Button from "components/buttons/Button";
|
||||
import Checkbox from "components/forms/fields/Checkbox";
|
||||
import validatePresence from "components/forms/validators/validate_presence";
|
||||
import CustomLink from "components/CustomLink";
|
||||
import { AppContext } from "context/app";
|
||||
@@ -87,13 +88,18 @@ interface IAppleUpdatesMdmConfigData {
|
||||
const createAppleOSUpdatesData = (
|
||||
applePlatform: ApplePlatform,
|
||||
minOsVersion: string,
|
||||
deadline: string
|
||||
deadline: string,
|
||||
updateNewHosts?: boolean
|
||||
): IAppleUpdatesMdmConfigData => {
|
||||
return {
|
||||
mdm: {
|
||||
[APPLE_PLATFORMS_TO_CONFIG_FIELDS[applePlatform]]: {
|
||||
minimum_version: minOsVersion,
|
||||
deadline,
|
||||
// Add update_new_hosts only for macOS right now.
|
||||
...(applePlatform === "darwin"
|
||||
? { update_new_hosts: updateNewHosts }
|
||||
: {}),
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -104,6 +110,7 @@ interface IAppleOSTargetFormProps {
|
||||
applePlatform: ApplePlatform;
|
||||
defaultMinOsVersion: string;
|
||||
defaultDeadline: string;
|
||||
defaultUpdateNewHosts?: boolean;
|
||||
refetchAppConfig: () => void;
|
||||
refetchTeamConfig: () => void;
|
||||
}
|
||||
@@ -113,6 +120,7 @@ const AppleOSTargetForm = ({
|
||||
applePlatform,
|
||||
defaultMinOsVersion,
|
||||
defaultDeadline,
|
||||
defaultUpdateNewHosts,
|
||||
refetchAppConfig,
|
||||
refetchTeamConfig,
|
||||
}: IAppleOSTargetFormProps) => {
|
||||
@@ -126,6 +134,9 @@ const AppleOSTargetForm = ({
|
||||
const [minOsVersionError, setMinOsVersionError] = useState<
|
||||
string | undefined
|
||||
>();
|
||||
const [updateNewHosts, setUpdateNewHosts] = useState<boolean>(
|
||||
defaultUpdateNewHosts || false
|
||||
);
|
||||
const [deadlineError, setDeadlineError] = useState<string | undefined>();
|
||||
|
||||
// FIXME: This behaves unexpectedly when a user switches tabs or changes the teams dropdown while the form is
|
||||
@@ -145,13 +156,14 @@ const AppleOSTargetForm = ({
|
||||
const updateData = createAppleOSUpdatesData(
|
||||
applePlatform,
|
||||
minOsVersion,
|
||||
deadline
|
||||
deadline,
|
||||
updateNewHosts
|
||||
);
|
||||
try {
|
||||
currentTeamId === APP_CONTEXT_NO_TEAM_ID
|
||||
? await configAPI.update(updateData)
|
||||
: await teamsAPI.update(updateData, currentTeamId);
|
||||
renderFlash("success", "Successfully updated minimum version!");
|
||||
renderFlash("success", "Successfully updated.");
|
||||
} catch {
|
||||
renderFlash("error", "Couldn’t update. Please try again.");
|
||||
} finally {
|
||||
@@ -172,32 +184,23 @@ const AppleOSTargetForm = ({
|
||||
};
|
||||
|
||||
const getMinimumVersionTooltip = () => {
|
||||
return (
|
||||
<>
|
||||
If an already enrolled host is below the minimum version,
|
||||
<br /> the host is updated to exactly the minimum version if it's
|
||||
<br /> available from Apple.
|
||||
<br />
|
||||
<br /> If a new or wiped host is below the minimum version and
|
||||
<br /> automatically enrolls (ADE), the host is updated to Apple's
|
||||
<br /> latest version during Setup Assistant.
|
||||
</>
|
||||
);
|
||||
return <>Enrolled hosts are updated to exactly this version.</>;
|
||||
};
|
||||
|
||||
return (
|
||||
<form className={baseClass} onSubmit={handleSubmit}>
|
||||
<InputField
|
||||
label="Minimum version"
|
||||
name="minimum_version"
|
||||
disabled={gitOpsModeEnabled}
|
||||
tooltip={getMinimumVersionTooltip()}
|
||||
helpText={
|
||||
<>
|
||||
Use only versions available from Apple.{" "}
|
||||
Use only versions{" "}
|
||||
<CustomLink
|
||||
text="Learn more"
|
||||
text="available from Apple."
|
||||
newTab
|
||||
url="https://fleetdm.com/learn-more-about/available-os-update-versions"
|
||||
url="https://fleetdm.com/learn-more-about/apple-available-os-updates"
|
||||
/>
|
||||
</>
|
||||
}
|
||||
@@ -207,6 +210,7 @@ const AppleOSTargetForm = ({
|
||||
/>
|
||||
<InputField
|
||||
disabled={gitOpsModeEnabled}
|
||||
name="deadline"
|
||||
label="Deadline"
|
||||
tooltip="The end user can't dismiss the OS update once they reach this deadline. Deadline is 12:00 (Noon), the host's local time."
|
||||
helpText="YYYY-MM-DD format only (e.g., “2024-07-01”)."
|
||||
@@ -214,6 +218,20 @@ const AppleOSTargetForm = ({
|
||||
error={deadlineError}
|
||||
onChange={handleDeadlineChange}
|
||||
/>
|
||||
{applePlatform === "darwin" && (
|
||||
<Checkbox
|
||||
name="update_new_hosts"
|
||||
disabled={gitOpsModeEnabled}
|
||||
onChange={setUpdateNewHosts}
|
||||
value={updateNewHosts}
|
||||
className={`${baseClass}__checkbox`}
|
||||
labelTooltipContent={
|
||||
"Hosts that automatically enroll (ADE) are updated to Apple's latest version during macOS Setup Assistant."
|
||||
}
|
||||
>
|
||||
Update new hosts to latest
|
||||
</Checkbox>
|
||||
)}
|
||||
<div className="button-wrap">
|
||||
<GitOpsModeTooltipWrapper
|
||||
position="right"
|
||||
|
||||
+6
-7
@@ -21,12 +21,11 @@ const OSRequirementDescription = ({
|
||||
case "darwin":
|
||||
return (
|
||||
<>
|
||||
<h3>End user experience on macOS</h3>
|
||||
<h3>End user experience</h3>
|
||||
<p>
|
||||
For macOS 14 and above, end users will see native macOS
|
||||
notifications (DDM).
|
||||
When a minimum version is enforced, end users see a native macOS
|
||||
notification (DDM) once per day.
|
||||
</p>
|
||||
<p>Everyone else will see the Nudge window.</p>
|
||||
<CustomLink
|
||||
text="Learn more"
|
||||
url="https://fleetdm.com/learn-more-about/os-updates"
|
||||
@@ -37,7 +36,7 @@ const OSRequirementDescription = ({
|
||||
case "windows":
|
||||
return (
|
||||
<>
|
||||
<h3>End user experience on Windows</h3>
|
||||
<h3>End user experience</h3>
|
||||
<p>
|
||||
When a Windows host becomes aware of a new update, end users are
|
||||
able to defer restarts. Automatic restarts happen before 8am and
|
||||
@@ -54,13 +53,13 @@ const OSRequirementDescription = ({
|
||||
case "ios":
|
||||
return (
|
||||
<>
|
||||
<h3>End user experience on iOS</h3>
|
||||
<h3>End user experience</h3>
|
||||
</>
|
||||
);
|
||||
case "ipados":
|
||||
return (
|
||||
<>
|
||||
<h3>End user experience on iPadOS</h3>
|
||||
<h3>End user experience</h3>
|
||||
</>
|
||||
);
|
||||
default:
|
||||
|
||||
@@ -19,6 +19,7 @@ interface IPlatformTabsProps {
|
||||
currentTeamId: number;
|
||||
defaultMacOSVersion: string;
|
||||
defaultMacOSDeadline: string;
|
||||
defaultMacOSUpdateNewHosts: boolean;
|
||||
defaultIOSVersion: string;
|
||||
defaultIOSDeadline: string;
|
||||
defaultIPadOSVersion: string;
|
||||
@@ -37,6 +38,7 @@ const PlatformTabs = ({
|
||||
currentTeamId,
|
||||
defaultMacOSDeadline,
|
||||
defaultMacOSVersion,
|
||||
defaultMacOSUpdateNewHosts,
|
||||
defaultIOSDeadline,
|
||||
defaultIOSVersion,
|
||||
defaultIPadOSDeadline,
|
||||
@@ -99,6 +101,7 @@ const PlatformTabs = ({
|
||||
applePlatform="darwin"
|
||||
defaultMinOsVersion={defaultMacOSVersion}
|
||||
defaultDeadline={defaultMacOSDeadline}
|
||||
defaultUpdateNewHosts={defaultMacOSUpdateNewHosts}
|
||||
key={currentTeamId}
|
||||
refetchAppConfig={refetchAppConfig}
|
||||
refetchTeamConfig={refetchTeamConfig}
|
||||
|
||||
+28
@@ -19,6 +19,27 @@ type GetDefaultFnParams = {
|
||||
teamConfig?: ITeamConfig;
|
||||
};
|
||||
|
||||
const getDefaultUpdateNewHosts = ({
|
||||
osType,
|
||||
currentTeamId,
|
||||
appConfig,
|
||||
teamConfig,
|
||||
}: GetDefaultFnParams) => {
|
||||
const mdmData =
|
||||
currentTeamId === API_NO_TEAM_ID ? appConfig?.mdm : teamConfig?.mdm;
|
||||
|
||||
switch (osType) {
|
||||
case "darwin":
|
||||
return !!mdmData?.macos_updates.update_new_hosts;
|
||||
case "ios":
|
||||
return !!mdmData?.ios_updates.update_new_hosts;
|
||||
case "ipados":
|
||||
return !!mdmData?.ipados_updates.update_new_hosts;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const getDefaultOSVersion = ({
|
||||
osType,
|
||||
currentTeamId,
|
||||
@@ -149,6 +170,12 @@ const TargetSection = ({
|
||||
appConfig,
|
||||
teamConfig,
|
||||
});
|
||||
const defaultMacOSUpdateNewHosts = getDefaultUpdateNewHosts({
|
||||
osType: "darwin",
|
||||
currentTeamId,
|
||||
appConfig,
|
||||
teamConfig,
|
||||
});
|
||||
|
||||
const defaultWindowsDeadlineDays = getDefaultWindowsDeadlineDays({
|
||||
currentTeamId,
|
||||
@@ -184,6 +211,7 @@ const TargetSection = ({
|
||||
defaultIPadOSDeadline={defaultIPadOSDeadline}
|
||||
defaultWindowsDeadlineDays={defaultWindowsDeadlineDays}
|
||||
defaultWindowsGracePeriodDays={defaultWindowsGracePeriodDays}
|
||||
defaultMacOSUpdateNewHosts={defaultMacOSUpdateNewHosts}
|
||||
selectedPlatform={selectedPlatform}
|
||||
onSelectPlatform={onSelectPlatform}
|
||||
refetchAppConfig={refetchAppConfig}
|
||||
|
||||
Reference in New Issue
Block a user