fleet/frontend/pages/hosts/details/DeviceUserPage/ManualEnrollMdmModal/ManualEnrollMdmModal.tsx
Jacob Shandling 60712144f2
UI: Add automatic EnrollMdm modal (#9455)
# Addresses #9365 

# Implements
MDM enrollment modal that handles both automatic and manual enrollment
instructions:
- Automatic:
<img width="1181" alt="Screenshot 2023-01-20 at 4 33 50 PM"
src="https://user-images.githubusercontent.com/61553566/213829293-6d4a5053-9a3c-4f52-8cf8-a6607dc8df4e.png">
- Manual:

<img width="1158" alt="Screenshot 2023-01-20 at 4 35 04 PM"
src="https://user-images.githubusercontent.com/61553566/213829369-73ae779d-14a8-4aa7-9c6a-b97d046d0dc1.png">

- Also includes (by mistake, but might as well include them now) some
small bash scripts for use in MDM development
# 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/` 
- [x] Updated testing inventory
- [x] Manual QA for all new/changed functionality

---------

Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
2023-01-30 11:44:33 -08:00

126 lines
3.5 KiB
TypeScript

import React, { useContext, useState } from "react";
import { useQuery } from "react-query";
import FileSaver from "file-saver";
import { NotificationContext } from "context/notification";
import DataError from "components/DataError";
import Button from "components/buttons/Button";
import Modal from "components/Modal";
import Spinner from "components/Spinner";
import mdmAPI from "services/entities/mdm";
interface IManualEnrollMdmModalProps {
onCancel: () => void;
token?: string;
}
const baseClass = "manual-enroll-mdm-modal enroll-mdm-modal";
const ManualEnrollMdmModal = ({
onCancel,
token = "",
}: IManualEnrollMdmModalProps): JSX.Element => {
const { renderFlash } = useContext(NotificationContext);
const [isDownloadingProfile, setIsDownloadingProfile] = useState(false);
const {
data: enrollmentProfile,
error: fetchMdmProfileError,
isFetching: isFetchingMdmProfile,
} = useQuery<string, Error>(
["enrollment profile"],
() => mdmAPI.downloadDeviceUserEnrollmentProfile(token),
{
refetchOnWindowFocus: false,
}
);
const onDownloadProfile = (evt: React.MouseEvent) => {
evt.preventDefault();
setIsDownloadingProfile(true);
setTimeout(() => setIsDownloadingProfile(false), 1000);
if (enrollmentProfile) {
const filename = "fleet-mdm-enrollment-profile.mobileconfig";
const file = new global.window.File([enrollmentProfile], filename, {
type: "application/x-apple-aspen-config",
});
FileSaver.saveAs(file);
} else {
renderFlash(
"error",
"Your enrollment profile could not be downloaded. Please try again."
);
}
return false;
};
if (isFetchingMdmProfile) {
return <Spinner />;
}
if (fetchMdmProfileError) {
return <DataError card />;
}
return (
<Modal title="Turn on MDM" onExit={onCancel} className={baseClass}>
<div>
<p className={`${baseClass}__description`}>
To turn on MDM, Apple Inc. requires that you download and install a
profile.
</p>
<ol>
<li>
{!isFetchingMdmProfile && (
<>
<span>Download your profile.</span>
</>
)}
{fetchMdmProfileError ? (
<span className={`${baseClass}__error`}>
{fetchMdmProfileError}
</span>
) : (
<Button
type="button"
onClick={onDownloadProfile}
variant="brand"
isLoading={isDownloadingProfile}
className={`${baseClass}__download-button`}
>
Download
</Button>
)}
</li>
<li>
From the Apple menu in the top left corner of your screen, select{" "}
<b>System Settings</b> or <b>System Preferences</b>.
</li>
<li>
In the search bar, type Profiles. Select <b>Profiles</b>, find and
select <b>Enrollment Profile</b>, and select <b>Install</b>.
</li>
<li>
Enter your password, and select <b>Enroll</b>.
</li>
<li>
Close this window and select <b>Refetch</b> on your My device page
to tell your organization that MDM is on.
</li>
</ol>
<div className="modal-cta-wrap">
<Button type="button" onClick={onCancel} variant="brand">
Done
</Button>
</div>
</div>
</Modal>
);
};
export default ManualEnrollMdmModal;