diff --git a/frontend/components/App/App.tsx b/frontend/components/App/App.tsx index ac237a085d..dd8eb1ea47 100644 --- a/frontend/components/App/App.tsx +++ b/frontend/components/App/App.tsx @@ -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( ["abm_tokens"], diff --git a/frontend/components/MDM/AndroidEnterpriseDeletedMessage/AndroidEnterpriseDeletedMessage.tsx b/frontend/components/MDM/AndroidEnterpriseDeletedMessage/AndroidEnterpriseDeletedMessage.tsx new file mode 100644 index 0000000000..bf4ef5308e --- /dev/null +++ b/frontend/components/MDM/AndroidEnterpriseDeletedMessage/AndroidEnterpriseDeletedMessage.tsx @@ -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 ( + + } + > + Android MDM is off because Android Enterprise was deleted in Google + Workspace. Please turn on Android MDM again. + + ); +}; + +export default AndroidEnterpriseDeletedMessage; diff --git a/frontend/components/MDM/AndroidEnterpriseDeletedMessage/index.ts b/frontend/components/MDM/AndroidEnterpriseDeletedMessage/index.ts new file mode 100644 index 0000000000..639ba838b0 --- /dev/null +++ b/frontend/components/MDM/AndroidEnterpriseDeletedMessage/index.ts @@ -0,0 +1 @@ +export { default } from "./AndroidEnterpriseDeletedMessage"; diff --git a/frontend/components/MainContent/MainContent.tsx b/frontend/components/MainContent/MainContent.tsx index cc9157cb6d..48ac1d6327 100644 --- a/frontend/components/MainContent/MainContent.tsx +++ b/frontend/components/MainContent/MainContent.tsx @@ -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 = ; + } else if (false) { + // TODO: remove this when API is ready + banner = ; } else if (isAppleBmExpired || willAppleBmExpire) { banner = ; } else if (needsAbmTermsRenewal) { diff --git a/frontend/context/app.tsx b/frontend/context/app.tsx index 5ea496514f..70ef7542d0 100644 --- a/frontend/context/app.tsx +++ b/frontend/context/app.tsx @@ -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, diff --git a/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/AndroidMdmPage/AndroidMdmPage.tsx b/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/AndroidMdmPage/AndroidMdmPage.tsx index 627902ba23..34242acbf6 100644 --- a/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/AndroidMdmPage/AndroidMdmPage.tsx +++ b/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/AndroidMdmPage/AndroidMdmPage.tsx @@ -118,7 +118,7 @@ interface ITurnOffAndroidMdmProps { const TurnOffAndroidMdm = ({ onClickTurnOff }: ITurnOffAndroidMdmProps) => { const { data, isLoading, isError } = useQuery( - ["androidEnterprise"], + ["android_enterprise"], () => mdmAndroidAPI.getAndroidEnterprise(), { ...DEFAULT_USE_QUERY_OPTIONS,