UI – Always allow i(Pad)OS Refetch; update copy and naming for broader "Apple" MDM (#20674)
## 1st part of #20467 - Update types/interfaces - Update MDM copy from "macOS" to "Apple" - Update MDM file, variable, classnames from "Mac" to "Apple" - Enable refetch for iPads and iPhones <img width="1341" alt="Screenshot 2024-07-23 at 4 14 46 PM" src="https://github.com/user-attachments/assets/3c322680-3c7f-40eb-a9da-6a14d0f1a358"> # Checklist for submitter If some of the following don't apply, delete the relevant line. <!-- Note that API documentation changes are now addressed by the product design team. --> - [x] Added/updated tests - [x] Manual QA for all new/changed functionality --------- Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
This commit is contained in:
co-authored by
Jacob Shandling
parent
95fc48c110
commit
40d91588ec
@@ -32,6 +32,7 @@ const DEFAULT_MDM_APPLE_VPP_APP_MOCK: IVppApp = {
|
||||
latest_version: "1.0",
|
||||
app_store_id: 1,
|
||||
added: false,
|
||||
platform: "darwin",
|
||||
};
|
||||
|
||||
export const createMockVppApp = (overrides?: Partial<IVppApp>): IVppApp => {
|
||||
|
||||
@@ -34,7 +34,7 @@ export interface ISoftware {
|
||||
name: string; // e.g., "Figma.app"
|
||||
version: string; // e.g., "2.1.11"
|
||||
bundle_identifier?: string | null; // e.g., "com.figma.Desktop"
|
||||
source: string; // e.g., "apps"
|
||||
source: string; // "apps" | "ipados" | "ios" | "programs" | ?
|
||||
generated_cpe: string;
|
||||
vulnerabilities: ISoftwareVulnerability[] | null;
|
||||
hosts_count?: number;
|
||||
@@ -90,7 +90,7 @@ export interface ISoftwareTitle {
|
||||
id: number;
|
||||
name: string;
|
||||
versions_count: number;
|
||||
source: string;
|
||||
source: string; // "apps" | "ios_apps" | "ipados_apps" | ?
|
||||
hosts_count: number;
|
||||
versions: ISoftwareTitleVersion[] | null;
|
||||
software_package: ISoftwarePackage | null;
|
||||
@@ -103,7 +103,7 @@ export interface ISoftwareTitleDetails {
|
||||
name: string;
|
||||
software_package: ISoftwarePackage | null;
|
||||
app_store_app: IAppStoreApp | null;
|
||||
source: string;
|
||||
source: string; // "apps" | "ios_apps" | "ipados_apps" | ?
|
||||
hosts_count: number;
|
||||
versions: ISoftwareTitleVersion[] | null;
|
||||
bundle_identifier?: string;
|
||||
@@ -128,7 +128,7 @@ export interface ISoftwareVersion {
|
||||
name: string; // e.g., "Figma.app"
|
||||
version: string; // e.g., "2.1.11"
|
||||
bundle_identifier?: string; // e.g., "com.figma.Desktop"
|
||||
source: string; // e.g., "apps"
|
||||
source: string; // "apps" | "ipados_apps" | "ios_apps" | ?
|
||||
browser: string; // e.g., "chrome"
|
||||
release: string; // TODO: on software/verions/:id?
|
||||
vendor: string;
|
||||
@@ -148,6 +148,8 @@ export const SOURCE_TYPE_CONVERSION: Record<string, string> = {
|
||||
atom_packages: "Package (Atom)", // Atom packages were removed from software inventory. Mapping is maintained for backwards compatibility. (2023-12-04)
|
||||
python_packages: "Package (Python)",
|
||||
apps: "Application (macOS)",
|
||||
ios: "Application (iOS)",
|
||||
ipados: "Application (iPadOS)",
|
||||
chrome_extensions: "Browser plugin", // chrome_extensions can include any chrome-based browser (e.g., edge), so we rely instead on the `browser` field computed by Fleet server and fallback to this value if it is not present.
|
||||
firefox_addons: "Browser plugin (Firefox)",
|
||||
safari_extensions: "Browser plugin (Safari)",
|
||||
|
||||
+6
-4
@@ -19,12 +19,12 @@ const AppleAutomaticEnrollmentCard = ({
|
||||
}: IAppleAutomaticEnrollmentCardProps) => {
|
||||
let icon = "";
|
||||
let msg =
|
||||
"To enable automatic enrollment for macOS devices, first turn on macOS MDM.";
|
||||
"To enable automatic enrollment for macOS, iOS, and iPadOS hosts, first turn on Apple MDM.";
|
||||
if (!turnOn && !configured) {
|
||||
msg =
|
||||
"Automatically enroll newly purchased macOS devices when they’re first unboxed and set up by your end user.";
|
||||
"Automatically enroll newly purchased Apple hosts when they're first unboxed and set up by your end user.";
|
||||
} else if (!turnOn && configured) {
|
||||
msg = "Automatic enrollment for macOS enabled.";
|
||||
msg = "Automatic enrollment for Apple (macOS, iOS, iPadOS) hosts enabled.";
|
||||
icon = "success";
|
||||
}
|
||||
|
||||
@@ -34,7 +34,9 @@ const AppleAutomaticEnrollmentCard = ({
|
||||
color="gray"
|
||||
>
|
||||
<div>
|
||||
{!icon && <h3>Automatic enrollment for macOS hosts</h3>}
|
||||
{!icon && (
|
||||
<h3>Automatic enrollment for Apple (macOS, iOS, iPadOS) hosts.</h3>
|
||||
)}
|
||||
<p>
|
||||
{icon ? (
|
||||
<span>
|
||||
|
||||
+7
-7
@@ -19,11 +19,11 @@ import ApplePushCertSetup from "./components/content/ApplePushCertSetup";
|
||||
import ApplePushCertInfo from "./components/content/ApplePushCertInfo";
|
||||
|
||||
import RenewCertModal from "./components/modals/RenewCertModal";
|
||||
import TurnOffMacOsMdmModal from "./components/modals/TurnOffMacOsMdmModal";
|
||||
import TurnOffAppleMdmModal from "./components/modals/TurnOffAppleMdmModal";
|
||||
|
||||
export const baseClass = "mac-os-mdm-page";
|
||||
export const baseClass = "apple-mdm-page";
|
||||
|
||||
const MacOSMdmPage = ({ router }: { router: InjectedRouter }) => {
|
||||
const AppleMdmPage = ({ router }: { router: InjectedRouter }) => {
|
||||
const { config } = useContext(AppContext);
|
||||
const { renderFlash } = useContext(NotificationContext);
|
||||
|
||||
@@ -65,10 +65,10 @@ const MacOSMdmPage = ({ router }: { router: InjectedRouter }) => {
|
||||
toggleTurnOffMdmModal();
|
||||
try {
|
||||
await mdmAppleAPI.deleteApplePushCertificate();
|
||||
renderFlash("success", "macOS MDM turned off successfully.");
|
||||
renderFlash("success", "MDM turned off successfully.");
|
||||
router.push(PATHS.ADMIN_INTEGRATIONS_MDM);
|
||||
} catch (e) {
|
||||
renderFlash("error", "Couldn’t turn off MDM. Please try again.");
|
||||
renderFlash("error", "Couldn't turn off MDM. Please try again.");
|
||||
setIsUpdating(false);
|
||||
}
|
||||
}, [renderFlash, router]);
|
||||
@@ -124,7 +124,7 @@ const MacOSMdmPage = ({ router }: { router: InjectedRouter }) => {
|
||||
/>
|
||||
)}
|
||||
{showTurnOffMdmModal && (
|
||||
<TurnOffMacOsMdmModal
|
||||
<TurnOffAppleMdmModal
|
||||
onCancel={toggleTurnOffMdmModal}
|
||||
onConfirm={turnOffMdm}
|
||||
/>
|
||||
@@ -134,4 +134,4 @@ const MacOSMdmPage = ({ router }: { router: InjectedRouter }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default MacOSMdmPage;
|
||||
export default AppleMdmPage;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
.mac-os-mdm-page {
|
||||
.apple-mdm-page {
|
||||
&__back-to-mdm {
|
||||
margin-bottom: $pad-xlarge;
|
||||
}
|
||||
+1
-1
@@ -28,7 +28,7 @@ const ApplePushCertSetup = ({
|
||||
setIsUploading(true);
|
||||
try {
|
||||
await mdmAppleApi.uploadApplePushCertificate(files[0]);
|
||||
renderFlash("success", "macOS MDM turned on successfully.");
|
||||
renderFlash("success", "MDM turned on successfully.");
|
||||
onSetupSuccess();
|
||||
} catch (e) {
|
||||
const msg = getErrorReason(e);
|
||||
+9
-8
@@ -4,17 +4,17 @@ import Button from "components/buttons/Button";
|
||||
|
||||
import Modal from "components/Modal";
|
||||
|
||||
const baseClass = "modal turn-off-mdm-modal";
|
||||
const baseClass = "modal turn-off-apple-mdm-modal";
|
||||
|
||||
interface ITurnOffMacOsMdmModalProps {
|
||||
interface ITurnOffAppleMdmModalProps {
|
||||
onCancel: () => void;
|
||||
onConfirm: () => void;
|
||||
}
|
||||
|
||||
const TurnOffMacOsMdmModal = ({
|
||||
const TurnOffAppleMdmModal = ({
|
||||
onConfirm,
|
||||
onCancel,
|
||||
}: ITurnOffMacOsMdmModalProps): JSX.Element => {
|
||||
}: ITurnOffAppleMdmModalProps): JSX.Element => {
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
|
||||
const onClickConfirm = useCallback(() => {
|
||||
@@ -23,10 +23,11 @@ const TurnOffMacOsMdmModal = ({
|
||||
}, [onConfirm]);
|
||||
|
||||
return (
|
||||
<Modal title="Turn off macOS MDM" onExit={onCancel} className={baseClass}>
|
||||
<Modal title="Turn off MDM" onExit={onCancel} className={baseClass}>
|
||||
<div className={baseClass}>
|
||||
If you want to use MDM features again, you’ll have to upload a new APNs
|
||||
certificate and all end users will have to turn MDM off and back on.
|
||||
If you want to use MDM features again, you'll have to upload a new
|
||||
APNs certificate and all end users will have to turn MDM off and back
|
||||
on.
|
||||
<div className="modal-cta-wrap">
|
||||
<Button
|
||||
type="button"
|
||||
@@ -50,4 +51,4 @@ const TurnOffMacOsMdmModal = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default TurnOffMacOsMdmModal;
|
||||
export default TurnOffAppleMdmModal;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
.turn-off-mdm-modal {
|
||||
.turn-off-apple-mdm-modal {
|
||||
&__info-header {
|
||||
margin-bottom: $pad-xlarge;
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
export { default } from "./TurnOffAppleMdmModal";
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from "./AppleMdmPage";
|
||||
-1
@@ -1 +0,0 @@
|
||||
export { default } from "./TurnOffMacOsMdmModal";
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from "./MacOSMdmPage";
|
||||
@@ -15,7 +15,7 @@ import SectionHeader from "components/SectionHeader";
|
||||
|
||||
import EndUserMigrationSection from "./components/EndUserMigrationSection/EndUserMigrationSection";
|
||||
import WindowsMdmCard from "./components/WindowsMdmCard/WindowsMdmCard";
|
||||
import MacOSMdmCard from "./components/MacOSMdmCard/MacOSMdmCard";
|
||||
import AppleMdmCard from "./components/AppleMdmCard/AppleMdmCard";
|
||||
|
||||
const baseClass = "mdm-settings";
|
||||
|
||||
@@ -49,8 +49,8 @@ const MdmSettings = ({ router }: IMdmSettingsProps) => {
|
||||
}
|
||||
);
|
||||
|
||||
const navigateToMacOSMdm = () => {
|
||||
router.push(PATHS.ADMIN_INTEGRATIONS_MDM_MAC);
|
||||
const navigateToAppleMdm = () => {
|
||||
router.push(PATHS.ADMIN_INTEGRATIONS_MDM_APPLE);
|
||||
};
|
||||
|
||||
const navigateToWindowsMdm = () => {
|
||||
@@ -65,11 +65,11 @@ const MdmSettings = ({ router }: IMdmSettingsProps) => {
|
||||
<Spinner />
|
||||
) : (
|
||||
<div className={`${baseClass}__section ${baseClass}__mdm-section`}>
|
||||
<MacOSMdmCard
|
||||
<AppleMdmCard
|
||||
appleAPNInfo={appleAPNInfo}
|
||||
errorData={errorMdmApple}
|
||||
turnOnMacOSMdm={navigateToMacOSMdm}
|
||||
viewDetails={navigateToMacOSMdm}
|
||||
turnOnAppleMdm={navigateToAppleMdm}
|
||||
viewDetails={navigateToAppleMdm}
|
||||
/>
|
||||
<WindowsMdmCard
|
||||
turnOnWindowsMdm={navigateToWindowsMdm}
|
||||
|
||||
+17
-17
@@ -7,17 +7,17 @@ import DataError from "components/DataError";
|
||||
import { AxiosError } from "axios";
|
||||
import { IMdmApple } from "interfaces/mdm";
|
||||
|
||||
const baseClass = "mac-os-mdm-card";
|
||||
const baseClass = "apple-mdm-card";
|
||||
|
||||
interface ITurnOnMacOSMdmProps {
|
||||
interface ITurnOnAppleMdmProps {
|
||||
onClickTurnOn: () => void;
|
||||
}
|
||||
|
||||
const TurnOnMacOSMdm = ({ onClickTurnOn }: ITurnOnMacOSMdmProps) => {
|
||||
const TurnOnAppleMdm = ({ onClickTurnOn }: ITurnOnAppleMdmProps) => {
|
||||
return (
|
||||
<div className={`${baseClass}__turn-on-mac-os`}>
|
||||
<div className={`${baseClass}__turn-on-apple-mdm`}>
|
||||
<div>
|
||||
<h3>Turn on macOS MDM</h3>
|
||||
<h3>Turn on Apple (macOS, iOS, iPadOS) MDM</h3>
|
||||
<p>Enforce settings, OS updates, disk encryption, and more.</p>
|
||||
</div>
|
||||
<Button variant="brand" onClick={onClickTurnOn}>
|
||||
@@ -27,16 +27,16 @@ const TurnOnMacOSMdm = ({ onClickTurnOn }: ITurnOnMacOSMdmProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
interface ITurnOffMacOSMdmProps {
|
||||
interface ITurnOffAppleMdmProps {
|
||||
onClickDetails: () => void;
|
||||
}
|
||||
|
||||
const SeeDetailsMacOSMdm = ({ onClickDetails }: ITurnOffMacOSMdmProps) => {
|
||||
const SeeDetailsAppleMdm = ({ onClickDetails }: ITurnOffAppleMdmProps) => {
|
||||
return (
|
||||
<div className={`${baseClass}__turn-off-mac-os`}>
|
||||
<div>
|
||||
<Icon name="success" />
|
||||
<p>macOS MDM turned on</p>
|
||||
<p>Apple (macOS, iOS, iPadOS) MDM turned on.</p>
|
||||
</div>
|
||||
<Button onClick={onClickDetails} variant="text-icon">
|
||||
<Icon name="pencil" />
|
||||
@@ -46,25 +46,25 @@ const SeeDetailsMacOSMdm = ({ onClickDetails }: ITurnOffMacOSMdmProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
interface IMacOSMdmCardProps {
|
||||
interface IAppleMdmCardProps {
|
||||
appleAPNInfo: IMdmApple | undefined;
|
||||
errorData: AxiosError | null;
|
||||
turnOnMacOSMdm: () => void;
|
||||
turnOnAppleMdm: () => void;
|
||||
viewDetails: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* This compoent is responsible for showing the correct UI for the macOS MDM card.
|
||||
* This component is responsible for showing the correct UI for the Apple MDM card.
|
||||
* We pass in the appleAPNInfo and errorData from the MdmSettings component because
|
||||
* we need to make that API call higher up in the component tree to correctly show
|
||||
* loading states on the page.
|
||||
*/
|
||||
const MacOSMdmCard = ({
|
||||
const AppleMdmCard = ({
|
||||
appleAPNInfo,
|
||||
errorData,
|
||||
turnOnMacOSMdm,
|
||||
turnOnAppleMdm,
|
||||
viewDetails,
|
||||
}: IMacOSMdmCardProps) => {
|
||||
}: IAppleMdmCardProps) => {
|
||||
// The API returns an error if MDM is turned off or APNS is not configured yet.
|
||||
// If there is any other error we will show the DataError component.
|
||||
const showError =
|
||||
@@ -77,12 +77,12 @@ const MacOSMdmCard = ({
|
||||
return (
|
||||
<Card className={baseClass} color="gray">
|
||||
{appleAPNInfo !== undefined ? (
|
||||
<SeeDetailsMacOSMdm onClickDetails={viewDetails} />
|
||||
<SeeDetailsAppleMdm onClickDetails={viewDetails} />
|
||||
) : (
|
||||
<TurnOnMacOSMdm onClickTurnOn={turnOnMacOSMdm} />
|
||||
<TurnOnAppleMdm onClickTurnOn={turnOnAppleMdm} />
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default MacOSMdmCard;
|
||||
export default AppleMdmCard;
|
||||
+17
-13
@@ -5,41 +5,45 @@ import { render, screen } from "@testing-library/react";
|
||||
import createMockMdmApple from "__mocks__/appleMdm";
|
||||
import createMockAxiosError from "__mocks__/axiosError";
|
||||
|
||||
import MacOSMdmCard from "./MacOSMdmCard";
|
||||
import AppleMdmCard from "./AppleMdmCard";
|
||||
|
||||
describe("MacOSMdmCard", () => {
|
||||
it("renders the turn on macOs mdm state when there is no appleAPNInfo", () => {
|
||||
describe("AppleMdmCard", () => {
|
||||
it("renders the turn on Apple mdm state when there is no appleAPNInfo", () => {
|
||||
render(
|
||||
<MacOSMdmCard
|
||||
<AppleMdmCard
|
||||
appleAPNInfo={undefined}
|
||||
errorData={null}
|
||||
turnOnMacOSMdm={noop}
|
||||
turnOnAppleMdm={noop}
|
||||
viewDetails={noop}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(screen.getByText("Turn on macOS MDM")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("Turn on Apple (macOS, iOS, iPadOS) MDM")
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders the show details state when there is appleAPNInfo", () => {
|
||||
render(
|
||||
<MacOSMdmCard
|
||||
<AppleMdmCard
|
||||
appleAPNInfo={createMockMdmApple()}
|
||||
errorData={null}
|
||||
turnOnMacOSMdm={noop}
|
||||
turnOnAppleMdm={noop}
|
||||
viewDetails={noop}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(screen.getByText("macOS MDM turned on")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("Apple (macOS, iOS, iPadOS) MDM turned on.")
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders the error state when there is a non 404 error", () => {
|
||||
render(
|
||||
<MacOSMdmCard
|
||||
<AppleMdmCard
|
||||
appleAPNInfo={createMockMdmApple()}
|
||||
errorData={createMockAxiosError({ status: 500 })}
|
||||
turnOnMacOSMdm={noop}
|
||||
turnOnAppleMdm={noop}
|
||||
viewDetails={noop}
|
||||
/>
|
||||
);
|
||||
@@ -47,10 +51,10 @@ describe("MacOSMdmCard", () => {
|
||||
expect(screen.getByText(/Something's gone wrong/)).toBeInTheDocument();
|
||||
|
||||
render(
|
||||
<MacOSMdmCard
|
||||
<AppleMdmCard
|
||||
appleAPNInfo={createMockMdmApple()}
|
||||
errorData={createMockAxiosError({ status: 404 })}
|
||||
turnOnMacOSMdm={noop}
|
||||
turnOnAppleMdm={noop}
|
||||
viewDetails={noop}
|
||||
/>
|
||||
);
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
.mac-os-mdm-card {
|
||||
.apple-mdm-card {
|
||||
font-size: $x-small;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&__turn-on-mac-os,
|
||||
&__turn-on-apple-mdm,
|
||||
&__turn-off-mac-os {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -22,7 +22,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
&__turn-on-mac-os {
|
||||
&__turn-on-apple-mdm {
|
||||
h3 {
|
||||
font-size: $x-small;
|
||||
font-weight: $bold;
|
||||
+1
@@ -0,0 +1 @@
|
||||
export { default } from "./AppleMdmCard";
|
||||
-1
@@ -1 +0,0 @@
|
||||
export { default } from "./MacOSMdmCard";
|
||||
@@ -29,7 +29,7 @@ describe("Vpp Section", () => {
|
||||
render(<Vpp router={createMockRouter()} />);
|
||||
|
||||
expect(
|
||||
await screen.findByRole("button", { name: "Turn on macOS MDM" })
|
||||
await screen.findByRole("button", { name: "Turn on MDM" })
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
||||
@@ -37,12 +37,12 @@ const VppCard = ({ isAppleMdmOn, isVppOn, router }: IVppCardProps) => {
|
||||
<div>
|
||||
<h3>Volume Purchasing Program (VPP)</h3>
|
||||
<p>
|
||||
To enable Volume Purchasing Program (VPP) for macOS devices, first
|
||||
turn on macOS MDM.
|
||||
To enable Volume Purchasing Program (VPP), first turn on Apple (macOS,
|
||||
iOS, iPadOS) MDM.
|
||||
</p>
|
||||
</div>
|
||||
<Button onClick={nagivateToMdm} variant="text-link">
|
||||
Turn on macOS MDM
|
||||
Turn on MDM
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
+1
-1
@@ -921,7 +921,7 @@ describe("Host Actions Dropdown", () => {
|
||||
expect(screen.queryByText("Wipe")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("does not renders when a macOS host but does not have Fleet macOS mdm enabled and configured", async () => {
|
||||
it("does not render for a macOS host if Fleet Apple MDM is not enabled and configured", async () => {
|
||||
const render = createCustomRenderer({
|
||||
context: {
|
||||
app: {
|
||||
|
||||
@@ -140,7 +140,7 @@ describe("Host Summary section", () => {
|
||||
});
|
||||
});
|
||||
describe("iOS and iPadOS data", () => {
|
||||
it("for iOS, renders Team, Disk space, and Operating system data only and hides the refetch button", async () => {
|
||||
it("for iOS, renders Team, Disk space, and Operating system data only", async () => {
|
||||
const render = createCustomRenderer({
|
||||
context: {
|
||||
app: {
|
||||
@@ -181,15 +181,15 @@ describe("Host Summary section", () => {
|
||||
expect(
|
||||
screen.getByText("Operating system").nextElementSibling
|
||||
).toHaveTextContent(osVersion);
|
||||
expect(screen.queryByText("Refetch")).toBeInTheDocument();
|
||||
|
||||
expect(screen.queryByText("Refetch")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Status")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Memory")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Processor type")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Agent")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Osquery")).not.toBeInTheDocument();
|
||||
});
|
||||
it("for iPadOS, renders Team, Disk space, and Operating system data only and hides the refetch button", async () => {
|
||||
it("for iPadOS, renders Team, Disk space, and Operating system data only", async () => {
|
||||
const render = createCustomRenderer({
|
||||
context: {
|
||||
app: {
|
||||
@@ -230,8 +230,8 @@ describe("Host Summary section", () => {
|
||||
expect(
|
||||
screen.getByText("Operating system").nextElementSibling
|
||||
).toHaveTextContent(osVersion);
|
||||
expect(screen.queryByText("Refetch")).toBeInTheDocument();
|
||||
|
||||
expect(screen.queryByText("Refetch")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Status")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Memory")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Processor type")).not.toBeInTheDocument();
|
||||
|
||||
@@ -191,30 +191,29 @@ const HostSummary = ({
|
||||
const isIosOrIpadosHost = platform === "ios" || platform === "ipados";
|
||||
|
||||
const renderRefetch = () => {
|
||||
if (isIosOrIpadosHost) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isOnline = summaryData.status === "online";
|
||||
let isDisabled = false;
|
||||
let tooltip: React.ReactNode = <></>;
|
||||
let tooltip;
|
||||
|
||||
// deviceStatus can be `undefined` in the case of the MyDevice Page not sending
|
||||
// this prop. When this is the case or when it is `unlocked`, we only take
|
||||
// into account the host being online or offline for correctly render the
|
||||
// refresh button. If we have a value for deviceStatus, we then need to also
|
||||
// take it account for rendering the button.
|
||||
if (
|
||||
hostMdmDeviceStatus === undefined ||
|
||||
hostMdmDeviceStatus === "unlocked"
|
||||
) {
|
||||
isDisabled = !isOnline;
|
||||
tooltip = !isOnline ? REFETCH_TOOLTIP_MESSAGES.offline : null;
|
||||
} else {
|
||||
isDisabled = true;
|
||||
tooltip = !isOnline
|
||||
? REFETCH_TOOLTIP_MESSAGES.offline
|
||||
: REFETCH_TOOLTIP_MESSAGES[hostMdmDeviceStatus];
|
||||
// we don't have a concept of "online" for iPads and iPhones, so always enable refetch
|
||||
if (!isIosOrIpadosHost) {
|
||||
// deviceStatus can be `undefined` in the case of the MyDevice Page not sending
|
||||
// this prop. When this is the case or when it is `unlocked`, we only take
|
||||
// into account the host being online or offline for correctly render the
|
||||
// refresh button. If we have a value for deviceStatus, we then need to also
|
||||
// take it account for rendering the button.
|
||||
if (
|
||||
hostMdmDeviceStatus === undefined ||
|
||||
hostMdmDeviceStatus === "unlocked"
|
||||
) {
|
||||
isDisabled = !isOnline;
|
||||
tooltip = !isOnline ? REFETCH_TOOLTIP_MESSAGES.offline : null;
|
||||
} else {
|
||||
isDisabled = true;
|
||||
tooltip = !isOnline
|
||||
? REFETCH_TOOLTIP_MESSAGES.offline
|
||||
: REFETCH_TOOLTIP_MESSAGES[hostMdmDeviceStatus];
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -57,7 +57,7 @@ import OSUpdates from "pages/ManageControlsPage/OSUpdates";
|
||||
import OSSettings from "pages/ManageControlsPage/OSSettings";
|
||||
import SetupExperience from "pages/ManageControlsPage/SetupExperience/SetupExperience";
|
||||
import WindowsMdmPage from "pages/admin/IntegrationsPage/cards/MdmSettings/WindowsMdmPage";
|
||||
import MacOSMdmPage from "pages/admin/IntegrationsPage/cards/MdmSettings/MacOSMdmPage";
|
||||
import AppleMdmPage from "pages/admin/IntegrationsPage/cards/MdmSettings/AppleMdmPage";
|
||||
import Scripts from "pages/ManageControlsPage/Scripts/Scripts";
|
||||
import AppleAutomaticEnrollmentPage from "pages/admin/IntegrationsPage/cards/AutomaticEnrollment/AppleAutomaticEnrollmentPage";
|
||||
import WindowsAutomaticEnrollmentPage from "pages/admin/IntegrationsPage/cards/AutomaticEnrollment/WindowsAutomaticEnrollmentPage";
|
||||
@@ -160,7 +160,7 @@ const routes = (
|
||||
</Route>
|
||||
</Route>
|
||||
<Route path="integrations/mdm/windows" component={WindowsMdmPage} />
|
||||
<Route path="integrations/mdm/apple" component={MacOSMdmPage} />
|
||||
<Route path="integrations/mdm/apple" component={AppleMdmPage} />
|
||||
<Route
|
||||
path="integrations/automatic-enrollment/apple"
|
||||
component={AppleAutomaticEnrollmentPage}
|
||||
|
||||
@@ -32,7 +32,7 @@ export default {
|
||||
ADMIN_INTEGRATIONS: `${URL_PREFIX}/settings/integrations`,
|
||||
ADMIN_INTEGRATIONS_TICKET_DESTINATIONS: `${URL_PREFIX}/settings/integrations/ticket-destinations`,
|
||||
ADMIN_INTEGRATIONS_MDM: `${URL_PREFIX}/settings/integrations/mdm`,
|
||||
ADMIN_INTEGRATIONS_MDM_MAC: `${URL_PREFIX}/settings/integrations/mdm/apple`,
|
||||
ADMIN_INTEGRATIONS_MDM_APPLE: `${URL_PREFIX}/settings/integrations/mdm/apple`,
|
||||
ADMIN_INTEGRATIONS_MDM_WINDOWS: `${URL_PREFIX}/settings/integrations/mdm/windows`,
|
||||
ADMIN_INTEGRATIONS_AUTOMATIC_ENROLLMENT: `${URL_PREFIX}/settings/integrations/automatic-enrollment`,
|
||||
ADMIN_INTEGRATIONS_AUTOMATIC_ENROLLMENT_APPLE: `${URL_PREFIX}/settings/integrations/automatic-enrollment/apple`,
|
||||
|
||||
@@ -13,6 +13,7 @@ export interface IVppApp {
|
||||
latest_version: string;
|
||||
app_store_id: number;
|
||||
added: boolean;
|
||||
platform: string; // "darwin" | "ios" | "ipados"
|
||||
}
|
||||
|
||||
interface IGetVppAppsResponse {
|
||||
|
||||
@@ -50,11 +50,9 @@ export interface ISoftwareVersionsResponse {
|
||||
export interface ISoftwareTitleResponse {
|
||||
software_title: ISoftwareTitleDetails;
|
||||
}
|
||||
|
||||
export interface ISoftwareVersionResponse {
|
||||
software: ISoftwareVersion;
|
||||
}
|
||||
|
||||
export interface ISoftwareVersionsQueryKey extends ISoftwareApiParams {
|
||||
scope: "software-versions";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user