add anroid enterprise deleted banner (#26685)

For #26207

added banner that shows when android enterprise has been deleted.

> TODO: this is only the frontend and will not work until BE work is
done. It will not show in the UI currently


![image](https://github.com/user-attachments/assets/842fd4d2-43fe-4b06-95ff-f2c7a43a8b9f)
This commit is contained in:
Gabriel Hernandez
2025-03-10 13:16:43 +00:00
committed by GitHub
parent 07ea0508e8
commit 20eb780ffd
6 changed files with 86 additions and 3 deletions
+18
View File
@@ -23,6 +23,7 @@ import mdmAppleBMAPI, {
import mdmAppleAPI, {
IGetVppTokensResponse,
} from "services/entities/mdm_apple";
import mdmAndroidAPI from "services/entities/mdm_android";
// @ts-ignore
import Fleet403 from "pages/errors/Fleet403";
@@ -81,6 +82,7 @@ const App = ({ children, location }: IAppProps): JSX.Element => {
setCurrentUser,
setConfig,
setEnrollSecret,
setAndroidEnterpriseDeleted,
setABMExpiry,
setAPNsExpiry,
setVppExpiry,
@@ -93,6 +95,22 @@ const App = ({ children, location }: IAppProps): JSX.Element => {
// We will do a series of API calls to get the data that we need to display
// warnings to the user about various token expirations.
useQuery(["android_enterprise"], () => mdmAndroidAPI.getAndroidEnterprise(), {
...DEFAULT_USE_QUERY_OPTIONS,
retry: false,
enabled:
false && // TODO: reenable when the BE is completed
!!isGlobalAdmin &&
!!config?.mdm.android_enabled_and_configured &&
config?.android_enabled, // TODO: remove android feature flag
onSuccess: () => {
setAndroidEnterpriseDeleted(false);
},
onError: () => {
setAndroidEnterpriseDeleted(true);
},
});
// Get the ABM tokens
useQuery<IGetAbmTokensResponse, AxiosError>(
["abm_tokens"],
@@ -0,0 +1,29 @@
import React from "react";
import CustomLink from "components/CustomLink";
import InfoBanner from "components/InfoBanner";
const baseClass = "android-enterprise-deleted-message";
const AndroidEnterpriseDeletedMessage = () => {
return (
<InfoBanner
className={baseClass}
color="yellow"
cta={
<CustomLink
url="https://business.apple.com/" // TODO: get this link
text="Learn more"
className={baseClass}
newTab
variant="banner-link"
/>
}
>
Android MDM is off because Android Enterprise was deleted in Google
Workspace. Please turn on Android MDM again.
</InfoBanner>
);
};
export default AndroidEnterpriseDeletedMessage;
@@ -0,0 +1 @@
export { default } from "./AndroidEnterpriseDeletedMessage";
@@ -1,13 +1,15 @@
import React, { ReactNode, useContext } from "react";
import classnames from "classnames";
import { hasLicenseExpired } from "utilities/helpers";
import { AppContext } from "context/app";
import AppleBMTermsMessage from "components/MDM/AppleBMTermsMessage";
import { AppContext } from "context/app";
import LicenseExpirationBanner from "components/LicenseExpirationBanner";
import ApplePNCertRenewalMessage from "components/MDM/ApplePNCertRenewalMessage";
import AppleBMRenewalMessage from "components/MDM/AppleBMRenewalMessage";
import AndroidEnterpriseDeletedMessage from "components/MDM/AndroidEnterpriseDeletedMessage";
import VppRenewalMessage from "./banners/VppRenewalMessage";
interface IMainContentProps {
@@ -32,6 +34,7 @@ const MainContent = ({
const {
config,
isPremiumTier,
isAndroidEnterpriseDeleted,
isApplePnsExpired,
isAppleBmExpired,
isVppExpired,
@@ -48,9 +51,14 @@ const MainContent = ({
let banner: JSX.Element | null = null;
// the order of these checks is important. This is the priority order
// for showing banners and only one banner is shown at a time.
if (isPremiumTier) {
if (isApplePnsExpired || willApplePnsExpire) {
banner = <ApplePNCertRenewalMessage expired={isApplePnsExpired} />;
} else if (false) {
// TODO: remove this when API is ready
banner = <AndroidEnterpriseDeletedMessage />;
} else if (isAppleBmExpired || willAppleBmExpire) {
banner = <AppleBMRenewalMessage expired={isAppleBmExpired} />;
} else if (needsAbmTermsRenewal) {
+27
View File
@@ -20,6 +20,7 @@ enum ACTIONS {
SET_CURRENT_TEAM = "SET_CURRENT_TEAM",
SET_CONFIG = "SET_CONFIG",
SET_ENROLL_SECRET = "SET_ENROLL_SECRET",
SET_ANDROID_ENTERPRISE_DELETED = "SET_ANDROID_ENTERPRISE_DELETED",
SET_ABM_EXPIRY = "SET_ABM_EXPIRY",
SET_APNS_EXPIRY = "SET_APNS_EXPIRY",
SET_VPP_EXPIRY = "SET_VPP_EXPIRY",
@@ -60,6 +61,11 @@ interface ISetEnrollSecretAction {
enrollSecret: IEnrollSecret[];
}
interface ISetAndroidEnterpriseDeletedAction {
type: ACTIONS.SET_ANDROID_ENTERPRISE_DELETED;
isDeleted: boolean;
}
interface IAbmExpiry {
earliestExpiry: string;
needsAbmTermsRenewal: boolean;
@@ -109,6 +115,7 @@ interface ISetFilteredPoliciesPathAction {
type: ACTIONS.SET_FILTERED_POLICIES_PATH;
filteredPoliciesPath: string;
}
type IAction =
| ISetAvailableTeamsAction
| ISetUserSettingsAction
@@ -116,6 +123,7 @@ type IAction =
| ISetCurrentTeamAction
| ISetCurrentUserAction
| ISetEnrollSecretAction
| ISetAndroidEnterpriseDeletedAction
| ISetABMExpiryAction
| ISetAPNsExpiryAction
| ISetVppExpiryAction
@@ -159,6 +167,7 @@ type InitialStateType = {
isOnlyObserver?: boolean;
isObserverPlus?: boolean;
isNoAccess?: boolean;
isAndroidEnterpriseDeleted: boolean;
isAppleBmExpired: boolean;
isApplePnsExpired: boolean;
isVppExpired: boolean;
@@ -185,6 +194,7 @@ type InitialStateType = {
setCurrentTeam: (team?: ITeamSummary) => void;
setConfig: (config: IConfig) => void;
setEnrollSecret: (enrollSecret: IEnrollSecret[]) => void;
setAndroidEnterpriseDeleted: (isDeleted: boolean) => void;
setAPNsExpiry: (apnsExpiry: string) => void;
setABMExpiry: (abmExpiry: IAbmExpiry) => void;
setVppExpiry: (vppExpiry: string) => void;
@@ -231,6 +241,7 @@ export const initialState = {
filteredSoftwarePath: undefined,
filteredQueriesPath: undefined,
filteredPoliciesPath: undefined,
isAndroidEnterpriseDeleted: false,
isAppleBmExpired: false,
isApplePnsExpired: false,
isVppExpired: false,
@@ -244,6 +255,7 @@ export const initialState = {
setCurrentTeam: () => null,
setConfig: () => null,
setEnrollSecret: () => null,
setAndroidEnterpriseDeleted: () => null,
setAPNsExpiry: () => null,
setABMExpiry: () => null,
setVppExpiry: () => null,
@@ -375,6 +387,13 @@ const reducer = (state: InitialStateType, action: IAction) => {
enrollSecret,
};
}
case ACTIONS.SET_ANDROID_ENTERPRISE_DELETED: {
const { isDeleted } = action;
return {
...state,
isAndroidEnterpriseDeleted: isDeleted,
};
}
case ACTIONS.SET_ABM_EXPIRY: {
const { abmExpiry } = action;
const { earliestExpiry, needsAbmTermsRenewal } = abmExpiry;
@@ -468,6 +487,7 @@ const AppProvider = ({ children }: Props): JSX.Element => {
abmExpiry: state.abmExpiry,
apnsExpiry: state.apnsExpiry,
vppExpiry: state.vppExpiry,
isAndroidEnterpriseDeleted: state.isAndroidEnterpriseDeleted,
isAppleBmExpired: state.isAppleBmExpired,
isApplePnsExpired: state.isApplePnsExpired,
isVppExpired: state.isVppExpired,
@@ -527,6 +547,12 @@ const AppProvider = ({ children }: Props): JSX.Element => {
setEnrollSecret: (enrollSecret: IEnrollSecret[]) => {
dispatch({ type: ACTIONS.SET_ENROLL_SECRET, enrollSecret });
},
setAndroidEnterpriseDeleted: (isDeleted: boolean) => {
dispatch({
type: ACTIONS.SET_ANDROID_ENTERPRISE_DELETED,
isDeleted,
});
},
setABMExpiry: (abmExpiry: IAbmExpiry) => {
dispatch({ type: ACTIONS.SET_ABM_EXPIRY, abmExpiry });
},
@@ -587,6 +613,7 @@ const AppProvider = ({ children }: Props): JSX.Element => {
state.isAnyTeamMaintainer,
state.isAnyTeamMaintainerOrTeamAdmin,
state.isAnyTeamObserverPlus,
state.isAndroidEnterpriseDeleted,
state.isAppleBmExpired,
state.isApplePnsExpired,
state.isFreeTier,
@@ -118,7 +118,7 @@ interface ITurnOffAndroidMdmProps {
const TurnOffAndroidMdm = ({ onClickTurnOff }: ITurnOffAndroidMdmProps) => {
const { data, isLoading, isError } = useQuery(
["androidEnterprise"],
["android_enterprise"],
() => mdmAndroidAPI.getAndroidEnterprise(),
{
...DEFAULT_USE_QUERY_OPTIONS,