handle all three ios and ipad unenrollment states and diplay correct copy in unenroll modal (#33804)
This is a quick fix to handle all three cases when showing the unenroll modal for ios and ipad devices. It also adds better naming to the functions that check the enrollment type. - [x] QA'd all new/changed functionality manually
This commit is contained in:
@@ -49,6 +49,7 @@ export type MdmEnrollmentStatus =
|
||||
| "On (manual)"
|
||||
| "On (automatic)"
|
||||
| "On (personal)"
|
||||
| "On (company-owned)"
|
||||
| "Off"
|
||||
| "Pending";
|
||||
|
||||
@@ -94,6 +95,10 @@ export const MDM_ENROLLMENT_STATUS_UI_MAP: Record<
|
||||
displayName: "Pending",
|
||||
filterValue: "pending",
|
||||
},
|
||||
"On (company-owned)": {
|
||||
displayName: "On (company-owned)",
|
||||
filterValue: "automatic",
|
||||
},
|
||||
};
|
||||
|
||||
export interface IMdmStatusCardData {
|
||||
@@ -261,7 +266,7 @@ export interface IMdmCommandResult {
|
||||
host_uuid: string;
|
||||
command_uuid: string;
|
||||
/** Status is the status of the command. It can be one of Acknowledged, Error, or NotNow for
|
||||
// Apple, or 200, 400, etc for Windows. */
|
||||
// Apple, or 200, 400, etc for Windows. */
|
||||
status: string;
|
||||
updated_at: string;
|
||||
request_type: string;
|
||||
@@ -278,14 +283,28 @@ export const isEnrolledInMdm = (
|
||||
if (!hostMdmEnrollmentStatus) {
|
||||
return false;
|
||||
}
|
||||
return ["On (automatic)", "On (manual)", "On (personal)"].includes(
|
||||
hostMdmEnrollmentStatus
|
||||
);
|
||||
return [
|
||||
"On (automatic)",
|
||||
"On (manual)",
|
||||
"On (personal)",
|
||||
"On (company-owned)",
|
||||
].includes(hostMdmEnrollmentStatus);
|
||||
};
|
||||
|
||||
/** determines if the host enrolled in mdm is a personal device */
|
||||
export const isPersonalEnrollmentInMdm = (
|
||||
export const isBYODManualEnrollment = (
|
||||
enrollmentStatus: MdmEnrollmentStatus | null
|
||||
) => {
|
||||
return enrollmentStatus === "On (manual)";
|
||||
};
|
||||
|
||||
export const isBYODAccountDrivenEnrollment = (
|
||||
enrollmentStatus: MdmEnrollmentStatus | null
|
||||
) => {
|
||||
return enrollmentStatus === "On (personal)";
|
||||
};
|
||||
|
||||
export const isCompanyOwnedEnrollment = (
|
||||
enrollmentStatus: MdmEnrollmentStatus | null
|
||||
) => {
|
||||
return enrollmentStatus === "On (company-owned)";
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
isAppleDevice,
|
||||
isMobilePlatform,
|
||||
} from "interfaces/platform";
|
||||
import { isPersonalEnrollmentInMdm } from "interfaces/mdm";
|
||||
import { isBYODAccountDrivenEnrollment } from "interfaces/mdm";
|
||||
|
||||
import TooltipWrapperArchLinuxRolling from "components/TooltipWrapperArchLinuxRolling";
|
||||
import Checkbox from "components/forms/fields/Checkbox";
|
||||
@@ -644,7 +644,9 @@ const allHostTableHeaders: IHostTableColumnConfig[] = [
|
||||
// TODO(android): is iOS/iPadOS supported?
|
||||
if (
|
||||
isAndroid(cellProps.row.original.platform) ||
|
||||
isPersonalEnrollmentInMdm(cellProps.row.original.mdm.enrollment_status)
|
||||
isBYODAccountDrivenEnrollment(
|
||||
cellProps.row.original.mdm.enrollment_status
|
||||
)
|
||||
) {
|
||||
return NotSupported;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,10 @@ import {
|
||||
isIPadOrIPhone,
|
||||
} from "interfaces/platform";
|
||||
import { isScriptSupportedPlatform } from "interfaces/script";
|
||||
import { isPersonalEnrollmentInMdm, MdmEnrollmentStatus } from "interfaces/mdm";
|
||||
import {
|
||||
isBYODAccountDrivenEnrollment,
|
||||
MdmEnrollmentStatus,
|
||||
} from "interfaces/mdm";
|
||||
|
||||
import {
|
||||
HostMdmDeviceStatusUIState,
|
||||
@@ -177,16 +180,16 @@ const canWipeHost = ({
|
||||
const canWipeWindowsOrAppleOS =
|
||||
hostMdmEnabled && isConnectedToFleetMdm && isEnrolledInMdm;
|
||||
|
||||
// there is a special case for iOS and iPadOS devices that are personally enrolled
|
||||
// there is a special case for iOS and iPadOS devices that are account driven enrolled
|
||||
// in MDM. These hosts cannot be wiped.
|
||||
const isPersonallyEnrolledIosOrIpadDevice =
|
||||
const isAccountDrivenEnrolledIosOrIpadosDevice =
|
||||
isIPadOrIPhone(hostPlatform) &&
|
||||
isPersonalEnrollmentInMdm(hostMdmEnrollmentStatus);
|
||||
isBYODAccountDrivenEnrollment(hostMdmEnrollmentStatus);
|
||||
|
||||
return (
|
||||
isPremiumTier &&
|
||||
!isAndroid(hostPlatform) &&
|
||||
!isPersonallyEnrolledIosOrIpadDevice &&
|
||||
!isAccountDrivenEnrolledIosOrIpadosDevice &&
|
||||
hostMdmDeviceStatus === "unlocked" &&
|
||||
(isLinuxLike(hostPlatform) || canWipeWindowsOrAppleOS) &&
|
||||
(isGlobalAdmin || isGlobalMaintainer || isTeamAdmin || isTeamMaintainer)
|
||||
|
||||
@@ -42,6 +42,7 @@ import {
|
||||
IHostCertificate,
|
||||
CERTIFICATES_DEFAULT_SORT,
|
||||
} from "interfaces/certificates";
|
||||
import { isBYODAccountDrivenEnrollment } from "interfaces/mdm";
|
||||
|
||||
import { normalizeEmptyValues, wrapFleetHelper } from "utilities/helpers";
|
||||
import permissions from "utilities/permissions";
|
||||
@@ -59,7 +60,6 @@ import {
|
||||
isIPadOrIPhone,
|
||||
isLinuxLike,
|
||||
} from "interfaces/platform";
|
||||
import { isPersonalEnrollmentInMdm } from "interfaces/mdm";
|
||||
|
||||
import Spinner from "components/Spinner";
|
||||
import TabNav from "components/TabNav";
|
||||
@@ -1021,10 +1021,10 @@ const HostDetailsPage = ({
|
||||
)}
|
||||
</TabPanel>
|
||||
<TabPanel>
|
||||
{/* There is a special case for personally enrolled mdm hosts where we are not
|
||||
{/* There is a special case for BYOD account driven enrolled mdm hosts where we are not
|
||||
currently supporting software installs. This check should be removed
|
||||
when we add that feature. */}
|
||||
{isPersonalEnrollmentInMdm(host.mdm.enrollment_status) ? (
|
||||
{isBYODAccountDrivenEnrollment(host.mdm.enrollment_status) ? (
|
||||
<EmptyTable
|
||||
header="Software library is currently not supported on this host."
|
||||
info={
|
||||
@@ -1351,14 +1351,12 @@ const HostDetailsPage = ({
|
||||
onProfileResent={refetchHostDetails}
|
||||
/>
|
||||
)}
|
||||
{showUnenrollMdmModal && !!host && (
|
||||
{showUnenrollMdmModal && !!host && host.mdm.enrollment_status && (
|
||||
<UnenrollMdmModal
|
||||
hostId={host.id}
|
||||
hostPlatform={host.platform}
|
||||
hostName={host.display_name}
|
||||
isBYODEnrollment={isPersonalEnrollmentInMdm(
|
||||
host.mdm.enrollment_status
|
||||
)}
|
||||
enrollmentStatus={host.mdm.enrollment_status}
|
||||
onClose={toggleUnenrollMdmModal}
|
||||
/>
|
||||
)}
|
||||
|
||||
+43
-20
@@ -4,25 +4,32 @@ import DataError from "components/DataError";
|
||||
import Button from "components/buttons/Button";
|
||||
import Modal from "components/Modal";
|
||||
import { NotificationContext } from "context/notification";
|
||||
import CustomLink from "components/CustomLink";
|
||||
|
||||
import mdmAPI from "services/entities/mdm";
|
||||
import { isAndroid, isIPadOrIPhone } from "interfaces/platform";
|
||||
import {
|
||||
isBYODAccountDrivenEnrollment,
|
||||
isBYODManualEnrollment,
|
||||
isCompanyOwnedEnrollment,
|
||||
MdmEnrollmentStatus,
|
||||
} from "interfaces/mdm";
|
||||
|
||||
const baseClass = "unenroll-mdm-modal";
|
||||
|
||||
interface IUnenrollMdmModalProps {
|
||||
hostId: number;
|
||||
hostPlatform: string;
|
||||
hostName: string;
|
||||
isBYODEnrollment?: boolean;
|
||||
enrollmentStatus: MdmEnrollmentStatus | null;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
const baseClass = "unenroll-mdm-modal";
|
||||
|
||||
const UnenrollMdmModal = ({
|
||||
hostId,
|
||||
hostPlatform,
|
||||
hostName,
|
||||
isBYODEnrollment = false,
|
||||
enrollmentStatus,
|
||||
onClose,
|
||||
}: IUnenrollMdmModalProps) => {
|
||||
const [requestState, setRequestState] = useState<
|
||||
@@ -66,27 +73,43 @@ const UnenrollMdmModal = ({
|
||||
setRequestState(undefined);
|
||||
};
|
||||
|
||||
const generateIosOrIpadosDescription = () => {
|
||||
if (isBYODManualEnrollment(enrollmentStatus)) {
|
||||
return (
|
||||
<p>
|
||||
To re-enroll, go to <b>Hosts > Add hosts > iOS/iPadOS</b> and
|
||||
share the link with end user.
|
||||
</p>
|
||||
);
|
||||
} else if (isBYODAccountDrivenEnrollment(enrollmentStatus)) {
|
||||
return (
|
||||
<p>
|
||||
To re-enroll, ask your end user to navigate to{" "}
|
||||
<b>
|
||||
Settings > General > VPN & Device Management > Sign in
|
||||
to Work or School Account...
|
||||
</b>{" "}
|
||||
on their host and to log in with their work email.
|
||||
</p>
|
||||
);
|
||||
} else if (isCompanyOwnedEnrollment(enrollmentStatus)) {
|
||||
return (
|
||||
<p>
|
||||
To re-enroll, make sure that the host is still in Apple Business
|
||||
Manager (ABM). The host will automatically enroll after it's
|
||||
reset.
|
||||
</p>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const generateDescription = () => {
|
||||
if (isIPadOrIPhone(hostPlatform)) {
|
||||
return (
|
||||
<>
|
||||
<p>Settings configured by Fleet will be removed.</p>
|
||||
{isBYODEnrollment ? (
|
||||
<p>
|
||||
To re-enroll, ask your end user to navigate to{" "}
|
||||
<b>
|
||||
Settings > General > VPN & Device Management > Sign
|
||||
in to Work or School Account...
|
||||
</b>{" "}
|
||||
on their host and to log in with their work email.
|
||||
</p>
|
||||
) : (
|
||||
<p>
|
||||
To re-enroll, make sure that the host is still in Apple Business
|
||||
Manager (ABM). The host will automatically enroll after it's
|
||||
reset.
|
||||
</p>
|
||||
)}
|
||||
{generateIosOrIpadosDescription()}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import classnames from "classnames";
|
||||
import { IHostMdmData, IMunkiData } from "interfaces/host";
|
||||
import { isAndroid, isIPadOrIPhone } from "interfaces/platform";
|
||||
import {
|
||||
isPersonalEnrollmentInMdm,
|
||||
isBYODAccountDrivenEnrollment,
|
||||
MDM_ENROLLMENT_STATUS_UI_MAP,
|
||||
} from "interfaces/mdm";
|
||||
import {
|
||||
@@ -55,7 +55,7 @@ const About = ({ aboutData, munki, mdm, className }: IAboutProps) => {
|
||||
// for all host types, we show the Enrollment ID dataset if the host
|
||||
// is enrolled in MDM personally. Personal (BYOD) devices do not report
|
||||
// their serial numbers, so we show the Enrollment ID instead.
|
||||
if (mdm && isPersonalEnrollmentInMdm(mdm.enrollment_status)) {
|
||||
if (mdm && isBYODAccountDrivenEnrollment(mdm.enrollment_status)) {
|
||||
deviceIdDataSet = (
|
||||
<DataSet
|
||||
title={
|
||||
|
||||
@@ -362,6 +362,7 @@ export const MDM_STATUS_TOOLTIP: Record<
|
||||
or by signing in with Google account. End user can turn MDM off.
|
||||
</span>
|
||||
),
|
||||
"On (company-owned)": null,
|
||||
Off: undefined, // no tooltip specified
|
||||
Pending: (
|
||||
<span>
|
||||
|
||||
Reference in New Issue
Block a user