Files
fleet/frontend/context/app.tsx
T
NicoandLucas Manuel Rodriguez ffe0f71c83 Technician role FE changes (#39494)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #38630

## Testing

- [x] QA'd all new/changed functionality manually

Screenshots below were taken with a **Team Technician** user. Same
changes apply for a **Global Technician**.

#### Controls > OS settings > Disk encryption

- Shows table without controls below.
- Shows empty state (doesn't allow to turn it on).

<img width="1915" height="886" alt="Screenshot 2026-02-10 at 12 24
25 PM"
src="https://github.com/user-attachments/assets/3f44d338-e728-4eb2-ad93-e30844201b52"
/>
<img width="1913" height="907" alt="Screenshot 2026-02-10 at 12 31
38 PM"
src="https://github.com/user-attachments/assets/71706e9e-0540-4c25-b5c0-3f7ccff3ba5a"
/>

#### Controls > OS settings > Custom settings

- Changed description to say **View configuration profiles that apply
custom settings.** instead of **Create and upload configuration profiles
to apply custom settings.**.
- **Add profile** not shown within table header.
- Trash can icon not shown when hovering over a row within the table.
- **Add profile** card not shown on empty state. Instead, "No
configuration profiles have been added." is shown.

<img width="1911" height="729" alt="Screenshot 2026-02-10 at 12 24
39 PM"
src="https://github.com/user-attachments/assets/aa68cbaf-4772-402d-9288-b4be2ddd3250"
/>
<img width="1912" height="650" alt="Screenshot 2026-02-10 at 12 28
48 PM"
src="https://github.com/user-attachments/assets/6a186172-b01f-4314-bb50-4cb533e13bce"
/>

#### Controls > Scripts > Library

- **Add script** not shown within table header.
- No actions shown when hovering over a table row.
- Can view script by clicking on a table row.
- Removed **To run the script across multiple hosts, add a policy
automation on the Policies page** line below **To run this script on a
host, go to the Hosts page and select a host.**.
- Updated copy to `To run this script on a host, go to the Hosts page
and select a host. Then, click Actions > Run script.`

<img width="1912" height="772" alt="Screenshot 2026-02-10 at 12 25
46 PM"
src="https://github.com/user-attachments/assets/83fbc1ec-3a6e-4bb5-865e-b5e7faef1e37"
/>

<img width="1732" height="761" alt="Screenshot 2026-02-11 at 3 50 33 PM"
src="https://github.com/user-attachments/assets/6dda97d7-fde2-4bcd-94b3-fa7368c65528"
/>


#### Labels

Can add label and filter by label

<img width="160" height="247" alt="Screenshot 2026-02-10 at 12 51 24 PM"
src="https://github.com/user-attachments/assets/ed63b708-27f8-4363-9d4f-9a7b0bf82b21"
/>

<img width="1901" height="856" alt="Screenshot 2026-02-10 at 12 35
07 PM"
src="https://github.com/user-attachments/assets/c2ef5e21-03ab-4955-a22f-cd6ca32f3179"
/>

<img width="1903" height="937" alt="Screenshot 2026-02-10 at 12 36
11 PM"
src="https://github.com/user-attachments/assets/d9d9f3bc-4d71-4c4b-902a-455eec9e057c"
/>

Can edit/delete labels created by themselves.
NOTE: my technician user ID is 37 - note that the **x** label belongs to
a different user id, while the second label belongs to ID 37, therefore
it can be edited and deleted.

<img width="1915" height="1152" alt="Screenshot 2026-02-10 at 12 38
29 PM"
src="https://github.com/user-attachments/assets/21f44c11-4e2d-456b-8547-90936b5d7602"
/>
<img width="1911" height="1154" alt="Screenshot 2026-02-10 at 12 38
42 PM"
src="https://github.com/user-attachments/assets/f9f7ea30-11b2-4d2d-9d71-de7299e4b451"
/>

Can delete manual label from host



https://github.com/user-attachments/assets/b64ba6dd-3f54-4dcd-9c57-7bede65122da

#### Host details

Can run scripts and view their results

<img width="1908" height="472" alt="Screenshot 2026-02-10 at 12 52
33 PM"
src="https://github.com/user-attachments/assets/d1e40339-ec52-47ff-bc53-c311498ffe80"
/>
<img width="1882" height="716" alt="Screenshot 2026-02-10 at 12 52
40 PM"
src="https://github.com/user-attachments/assets/dd0c2ec3-8cb8-4835-9c6d-f731a7434637"
/>
<img width="1915" height="718" alt="Screenshot 2026-02-10 at 12 52
48 PM"
src="https://github.com/user-attachments/assets/5e7a73e0-ac5b-4d38-b635-770f53dea9e3"
/>
<img width="1914" height="718" alt="Screenshot 2026-02-10 at 12 52
55 PM"
src="https://github.com/user-attachments/assets/b199c796-66b1-46bc-b2b5-fd35e8aa7a7c"
/>

Can run query associated to host as a live query




https://github.com/user-attachments/assets/7aea6f63-e443-4fa0-87dc-48bef84efa2f

#### Software

Doesn't show trash can icon on software installer card, just the
download one.

<img width="1423" height="838" alt="Screenshot 2026-02-10 at 1 33 53 PM"
src="https://github.com/user-attachments/assets/3a55c226-0bba-43ac-8594-7b5ac0a3684a"
/>

Can install/uninstall software on a host. Note that **Add software**
button is hidden (technicians can't add software).

<img width="1378" height="277" alt="Screenshot 2026-02-10 at 3 08 55 PM"
src="https://github.com/user-attachments/assets/bf413467-2071-48b6-b62b-f3a721b6057c"
/>



#### Queries

- Can run inherited queries on all hosts


https://github.com/user-attachments/assets/09f07e6b-a8c1-453e-81fd-4deb16005836

- Can run team queries on all hosts


https://github.com/user-attachments/assets/18b62dea-e159-40ea-b0ed-1d96b6bd40e7

- Can't manage automations or add queries (buttons are not shown at the
top-right corner)

#### Policies

Same as Queries



https://github.com/user-attachments/assets/2c24514a-2ae0-47a6-b631-6f9e48fc7b9c

#### Protected routes

Tested that I can't access routes that have restricted functionality for
this role, such as:

- **/controls/os-updates**, **/controls/setup-experience** and
**/controls/os-settings/certificates** => redirects to
**/controls/os-settings** 
- **/controls/scripts/progress** => redirects to
**/controls/scripts/library** 
- **/queries/new** and **/software/add/*** => renders access denied page


---------

Co-authored-by: Lucas Manuel Rodriguez <lucas@fleetdm.com>
2026-02-11 18:38:41 -03:00

674 lines
20 KiB
TypeScript

import React, { createContext, useReducer, useMemo, ReactNode } from "react";
import { IConfig, IUserSettings } from "interfaces/config";
import { IEnrollSecret } from "interfaces/enroll_secret";
import {
APP_CONTEXT_ALL_TEAMS_SUMMARY,
ITeamSummary,
APP_CONTEXT_NO_TEAM_SUMMARY,
APP_CONTEXT_NO_TEAM_ID,
} from "interfaces/team";
import { IUser } from "interfaces/user";
import permissions from "utilities/permissions";
import sort from "utilities/sort";
import { hasLicenseExpired, willExpireWithinXDays } from "utilities/helpers";
enum ACTIONS {
SET_AVAILABLE_TEAMS = "SET_AVAILABLE_TEAMS",
SET_USER_SETTINGS = "SET_USER_SETTINGS",
SET_CURRENT_USER = "SET_CURRENT_USER",
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",
SET_SANDBOX_EXPIRY = "SET_SANDBOX_EXPIRY",
SET_NO_SANDBOX_HOSTS = "SET_NO_SANDBOX_HOSTS",
SET_FILTERED_HOSTS_PATH = "SET_FILTERED_HOSTS_PATH",
SET_FILTERED_SOFTWARE_PATH = "SET_FILTERED_SOFTWARE_PATH",
SET_FILTERED_QUERIES_PATH = "SET_FILTERED_QUERIES_PATH",
SET_FILTERED_POLICIES_PATH = "SET_FILTERED_POLICIES_PATH",
}
interface ISetAvailableTeamsAction {
type: ACTIONS.SET_AVAILABLE_TEAMS;
user: IUser | null;
availableTeams: ITeamSummary[];
}
interface ISetUserSettingsAction {
type: ACTIONS.SET_USER_SETTINGS;
userSettings: IUserSettings;
}
interface ISetConfigAction {
type: ACTIONS.SET_CONFIG;
config: IConfig;
}
interface ISetCurrentTeamAction {
type: ACTIONS.SET_CURRENT_TEAM;
currentTeam: ITeamSummary | undefined;
}
interface ISetCurrentUserAction {
type: ACTIONS.SET_CURRENT_USER;
currentUser: IUser;
}
interface ISetEnrollSecretAction {
type: ACTIONS.SET_ENROLL_SECRET;
enrollSecret: IEnrollSecret[];
}
interface ISetAndroidEnterpriseDeletedAction {
type: ACTIONS.SET_ANDROID_ENTERPRISE_DELETED;
isDeleted: boolean;
}
interface IAbmExpiry {
earliestExpiry: string;
needsAbmTermsRenewal: boolean;
}
interface ISetABMExpiryAction {
type: ACTIONS.SET_ABM_EXPIRY;
abmExpiry: IAbmExpiry;
}
interface ISetAPNsExpiryAction {
type: ACTIONS.SET_APNS_EXPIRY;
apnsExpiry: string;
}
interface ISetVppExpiryAction {
type: ACTIONS.SET_VPP_EXPIRY;
vppExpiry: string;
}
interface ISetSandboxExpiryAction {
type: ACTIONS.SET_SANDBOX_EXPIRY;
sandboxExpiry: string;
}
interface ISetNoSandboxHostsAction {
type: ACTIONS.SET_NO_SANDBOX_HOSTS;
noSandboxHosts: boolean;
}
interface ISetFilteredHostsPathAction {
type: ACTIONS.SET_FILTERED_HOSTS_PATH;
filteredHostsPath: string;
}
interface ISetFilteredSoftwarePathAction {
type: ACTIONS.SET_FILTERED_SOFTWARE_PATH;
filteredSoftwarePath: string;
}
interface ISetFilteredQueriesPathAction {
type: ACTIONS.SET_FILTERED_QUERIES_PATH;
filteredQueriesPath: string;
}
interface ISetFilteredPoliciesPathAction {
type: ACTIONS.SET_FILTERED_POLICIES_PATH;
filteredPoliciesPath: string;
}
type IAction =
| ISetAvailableTeamsAction
| ISetUserSettingsAction
| ISetConfigAction
| ISetCurrentTeamAction
| ISetCurrentUserAction
| ISetEnrollSecretAction
| ISetAndroidEnterpriseDeletedAction
| ISetABMExpiryAction
| ISetAPNsExpiryAction
| ISetVppExpiryAction
| ISetSandboxExpiryAction
| ISetNoSandboxHostsAction
| ISetFilteredHostsPathAction
| ISetFilteredSoftwarePathAction
| ISetFilteredQueriesPathAction
| ISetFilteredPoliciesPathAction;
type Props = {
children: ReactNode;
};
type InitialStateType = {
availableTeams?: ITeamSummary[];
userSettings?: IUserSettings;
config: IConfig | null;
currentUser: IUser | null;
currentTeam?: ITeamSummary;
enrollSecret: IEnrollSecret[] | null;
isPreviewMode?: boolean;
isSandboxMode?: boolean;
isFreeTier?: boolean;
isPremiumTier?: boolean;
isMacMdmEnabledAndConfigured?: boolean;
isWindowsMdmEnabledAndConfigured?: boolean;
isAndroidMdmEnabledAndConfigured?: boolean;
isGlobalAdmin?: boolean;
isGlobalMaintainer?: boolean;
isGlobalObserver?: boolean;
isOnGlobalTeam?: boolean;
isAnyTeamObserverPlus?: boolean;
isAnyTeamMaintainer?: boolean;
isAnyTeamMaintainerOrTeamAdmin?: boolean;
isTeamObserver?: boolean;
isTeamMaintainer?: boolean;
isTeamMaintainerOrTeamAdmin?: boolean;
isAnyTeamAdmin?: boolean;
isTeamAdmin?: boolean;
isTeamTechnician?: boolean;
isAnyTeamTechnician?: boolean;
isGlobalTechnician?: boolean;
isOnlyObserver?: boolean;
isObserverPlus?: boolean;
isNoAccess?: boolean;
isAnyMaintainerAdminObserverPlus?: boolean;
isAndroidEnterpriseDeleted: boolean;
isAppleBmExpired: boolean;
isApplePnsExpired: boolean;
isVppExpired: boolean;
needsAbmTermsRenewal: boolean;
willAppleBmExpire: boolean;
willApplePnsExpire: boolean;
willVppExpire: boolean;
abmExpiry?: IAbmExpiry;
apnsExpiry?: string;
vppExpiry?: string;
sandboxExpiry?: string;
noSandboxHosts?: boolean;
filteredHostsPath?: string;
filteredSoftwarePath?: string;
filteredQueriesPath?: string;
filteredPoliciesPath?: string;
isVppEnabled?: boolean;
setAvailableTeams: (
user: IUser | null,
availableTeams: ITeamSummary[]
) => void;
setUserSettings: (userSettings: IUserSettings) => void;
setCurrentUser: (user: IUser) => void;
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;
setSandboxExpiry: (sandboxExpiry: string) => void;
setNoSandboxHosts: (noSandboxHosts: boolean) => void;
setFilteredHostsPath: (filteredHostsPath: string) => void;
setFilteredSoftwarePath: (filteredSoftwarePath: string) => void;
setFilteredQueriesPath: (filteredQueriesPath: string) => void;
setFilteredPoliciesPath: (filteredPoliciesPath: string) => void;
};
export type IAppContext = InitialStateType;
export const initialState = {
availableTeams: undefined,
userSettings: undefined,
config: null,
currentUser: null,
currentTeam: undefined,
enrollSecret: null,
isPreviewMode: false,
isSandboxMode: false,
isFreeTier: undefined,
isPremiumTier: undefined,
isMacMdmEnabledAndConfigured: undefined,
isWindowsMdmEnabledAndConfigured: undefined,
isAndroidMdmEnabledAndConfigured: undefined,
isGlobalAdmin: undefined,
isGlobalMaintainer: undefined,
isGlobalObserver: undefined,
isOnGlobalTeam: undefined,
isAnyTeamObserverPlus: undefined,
isAnyTeamMaintainer: undefined,
isAnyTeamMaintainerOrTeamAdmin: undefined,
isTeamObserver: undefined,
isTeamMaintainer: undefined,
isTeamMaintainerOrTeamAdmin: undefined,
isAnyTeamAdmin: undefined,
isTeamAdmin: undefined,
isTeamTechnician: undefined,
isAnyTeamTechnician: undefined,
isGlobalTechnician: undefined,
isOnlyObserver: undefined,
isObserverPlus: undefined,
isNoAccess: undefined,
isAnyMaintainerAdminObserverPlus: undefined,
filteredHostsPath: undefined,
filteredSoftwarePath: undefined,
filteredQueriesPath: undefined,
filteredPoliciesPath: undefined,
isAndroidEnterpriseDeleted: false,
isAppleBmExpired: false,
isApplePnsExpired: false,
isVppExpired: false,
needsAbmTermsRenewal: false,
willAppleBmExpire: false,
willApplePnsExpire: false,
willVppExpire: false,
setAvailableTeams: () => null,
setUserSettings: () => null,
setCurrentUser: () => null,
setCurrentTeam: () => null,
setConfig: () => null,
setEnrollSecret: () => null,
setAndroidEnterpriseDeleted: () => null,
setAPNsExpiry: () => null,
setABMExpiry: () => null,
setVppExpiry: () => null,
setSandboxExpiry: () => null,
setNoSandboxHosts: () => null,
setFilteredHostsPath: () => null,
setFilteredSoftwarePath: () => null,
setFilteredQueriesPath: () => null,
setFilteredPoliciesPath: () => null,
};
const detectPreview = () => {
return window.location.origin === "http://localhost:1337";
};
// helper function - this is run every
// time currentUser, currentTeam, config, or teamId is changed
const setPermissions = (
user: IUser | null,
config: IConfig | null,
teamId = APP_CONTEXT_NO_TEAM_ID
) => {
if (!user || !config) {
return {};
}
if (teamId < APP_CONTEXT_NO_TEAM_ID) {
teamId = APP_CONTEXT_NO_TEAM_ID;
}
return {
isSandboxMode: permissions.isSandboxMode(config),
isFreeTier: permissions.isFreeTier(config),
isPremiumTier: permissions.isPremiumTier(config),
isMacMdmEnabledAndConfigured: permissions.isMacMdmEnabledAndConfigured(
config
),
isWindowsMdmEnabledAndConfigured: permissions.isWindowsMdmEnabledAndConfigured(
config
),
isAndroidMdmEnabledAndConfigured: permissions.isAndroidMdmEnabledAndConfigured(
config
),
isGlobalAdmin: permissions.isGlobalAdmin(user),
isGlobalMaintainer: permissions.isGlobalMaintainer(user),
isGlobalObserver: permissions.isGlobalObserver(user),
isGlobalTechnician: permissions.isGlobalTechnician(user),
isOnGlobalTeam: permissions.isOnGlobalTeam(user),
isAnyTeamObserverPlus: permissions.isAnyTeamObserverPlus(user),
isAnyTeamMaintainer: permissions.isAnyTeamMaintainer(user),
isAnyTeamMaintainerOrTeamAdmin: permissions.isAnyTeamMaintainerOrTeamAdmin(
user
),
isAnyTeamAdmin: permissions.isAnyTeamAdmin(user),
isTeamObserver: permissions.isTeamObserver(user, teamId),
isTeamMaintainer: permissions.isTeamMaintainer(user, teamId),
isTeamAdmin: permissions.isTeamAdmin(user, teamId),
isTeamTechnician: permissions.isTeamTechnician(user, teamId),
isAnyTeamTechnician: permissions.isAnyTeamTechnician(user),
isTeamMaintainerOrTeamAdmin: permissions.isTeamMaintainerOrTeamAdmin(
user,
teamId
),
isOnlyObserver: permissions.isOnlyObserver(user),
isObserverPlus: permissions.isObserverPlus(user, teamId),
isNoAccess: permissions.isNoAccess(user),
};
};
const reducer = (state: InitialStateType, action: IAction) => {
switch (action.type) {
case ACTIONS.SET_USER_SETTINGS: {
const { userSettings } = action;
return {
...state,
userSettings,
};
}
case ACTIONS.SET_AVAILABLE_TEAMS: {
const { user, availableTeams } = action;
let sortedTeams = availableTeams.sort(
(a: ITeamSummary, b: ITeamSummary) =>
sort.caseInsensitiveAsc(a.name, b.name)
);
sortedTeams = sortedTeams.filter(
(t) =>
t.name !== APP_CONTEXT_ALL_TEAMS_SUMMARY.name &&
t.name !== APP_CONTEXT_NO_TEAM_SUMMARY.name
);
if (user && permissions.isOnGlobalTeam(user)) {
sortedTeams.unshift(
APP_CONTEXT_ALL_TEAMS_SUMMARY,
APP_CONTEXT_NO_TEAM_SUMMARY
);
}
return {
...state,
availableTeams: sortedTeams,
};
}
case ACTIONS.SET_CURRENT_USER: {
const { currentUser } = action;
return {
...state,
currentUser,
...setPermissions(currentUser, state.config, state.currentTeam?.id),
};
}
case ACTIONS.SET_CURRENT_TEAM: {
const { currentTeam } = action;
return {
...state,
currentTeam,
...setPermissions(state.currentUser, state.config, currentTeam?.id),
};
}
case ACTIONS.SET_CONFIG: {
const { config } = action;
return {
...state,
config,
...setPermissions(state.currentUser, config, state.currentTeam?.id),
};
}
case ACTIONS.SET_ENROLL_SECRET: {
const { enrollSecret } = action;
return {
...state,
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;
return {
...state,
abmExpiry,
isAppleBmExpired: hasLicenseExpired(earliestExpiry),
willAppleBmExpire: willExpireWithinXDays(earliestExpiry, 30),
needsAbmTermsRenewal,
};
}
case ACTIONS.SET_APNS_EXPIRY: {
const { apnsExpiry } = action;
return {
...state,
apnsExpiry,
isApplePnsExpired: hasLicenseExpired(apnsExpiry),
willApplePnsExpire: willExpireWithinXDays(apnsExpiry, 30),
};
}
case ACTIONS.SET_VPP_EXPIRY: {
const { vppExpiry } = action;
return {
...state,
vppExpiry,
isVppExpired: hasLicenseExpired(vppExpiry),
willVppExpire: willExpireWithinXDays(vppExpiry, 30),
};
}
case ACTIONS.SET_SANDBOX_EXPIRY: {
const { sandboxExpiry } = action;
return {
...state,
sandboxExpiry,
};
}
case ACTIONS.SET_NO_SANDBOX_HOSTS: {
const { noSandboxHosts } = action;
return {
...state,
noSandboxHosts,
};
}
case ACTIONS.SET_FILTERED_HOSTS_PATH: {
const { filteredHostsPath } = action;
return {
...state,
filteredHostsPath,
};
}
case ACTIONS.SET_FILTERED_SOFTWARE_PATH: {
const { filteredSoftwarePath } = action;
return {
...state,
filteredSoftwarePath,
};
}
case ACTIONS.SET_FILTERED_QUERIES_PATH: {
const { filteredQueriesPath } = action;
return {
...state,
filteredQueriesPath,
};
}
case ACTIONS.SET_FILTERED_POLICIES_PATH: {
const { filteredPoliciesPath } = action;
return {
...state,
filteredPoliciesPath,
};
}
default:
return state;
}
};
export const AppContext = createContext<InitialStateType>(initialState);
const AppProvider = ({ children }: Props): JSX.Element => {
const [state, dispatch] = useReducer(reducer, initialState);
const value = useMemo(
() => ({
availableTeams: state.availableTeams,
userSettings: state.userSettings,
config: state.config,
currentUser: state.currentUser,
currentTeam: state.currentTeam,
enrollSecret: state.enrollSecret,
sandboxExpiry: state.sandboxExpiry,
abmExpiry: state.abmExpiry,
apnsExpiry: state.apnsExpiry,
vppExpiry: state.vppExpiry,
isAndroidEnterpriseDeleted: state.isAndroidEnterpriseDeleted,
isAppleBmExpired: state.isAppleBmExpired,
isApplePnsExpired: state.isApplePnsExpired,
isVppExpired: state.isVppExpired,
needsAbmTermsRenewal: state.needsAbmTermsRenewal,
willAppleBmExpire: state.willAppleBmExpire,
willApplePnsExpire: state.willApplePnsExpire,
willVppExpire: state.willVppExpire,
noSandboxHosts: state.noSandboxHosts,
filteredHostsPath: state.filteredHostsPath,
filteredSoftwarePath: state.filteredSoftwarePath,
filteredQueriesPath: state.filteredQueriesPath,
filteredPoliciesPath: state.filteredPoliciesPath,
isPreviewMode: detectPreview(),
isSandboxMode: state.isSandboxMode,
isFreeTier: state.isFreeTier,
isPremiumTier: state.isPremiumTier,
isMacMdmEnabledAndConfigured: state.isMacMdmEnabledAndConfigured,
isWindowsMdmEnabledAndConfigured: state.isWindowsMdmEnabledAndConfigured,
isAndroidMdmEnabledAndConfigured: state.isAndroidMdmEnabledAndConfigured,
isGlobalAdmin: state.isGlobalAdmin,
isGlobalMaintainer: state.isGlobalMaintainer,
isGlobalObserver: state.isGlobalObserver,
isOnGlobalTeam: state.isOnGlobalTeam,
isAnyTeamObserverPlus: state.isAnyTeamObserverPlus,
isAnyTeamMaintainer: state.isAnyTeamMaintainer,
isAnyTeamMaintainerOrTeamAdmin: state.isAnyTeamMaintainerOrTeamAdmin,
isTeamObserver: state.isTeamObserver,
isTeamMaintainer: state.isTeamMaintainer,
isTeamAdmin: state.isTeamAdmin,
isTeamTechnician: state.isTeamTechnician,
isAnyTeamTechnician: state.isAnyTeamTechnician,
isGlobalTechnician: state.isGlobalTechnician,
isTeamMaintainerOrTeamAdmin: state.isTeamMaintainerOrTeamAdmin,
isAnyTeamAdmin: state.isAnyTeamAdmin,
isOnlyObserver: state.isOnlyObserver,
isObserverPlus: state.isObserverPlus,
isNoAccess: state.isNoAccess,
isAnyMaintainerAdminObserverPlus:
state.isGlobalAdmin ||
state.isGlobalMaintainer ||
state.isAnyTeamAdmin ||
state.isAnyTeamMaintainer ||
state.isObserverPlus ||
state.isAnyTeamObserverPlus,
setAvailableTeams: (
user: IUser | null,
availableTeams: ITeamSummary[]
) => {
dispatch({
type: ACTIONS.SET_AVAILABLE_TEAMS,
user,
availableTeams,
});
},
setUserSettings: (userSettings: IUserSettings) => {
dispatch({ type: ACTIONS.SET_USER_SETTINGS, userSettings });
},
setCurrentUser: (currentUser: IUser) => {
dispatch({ type: ACTIONS.SET_CURRENT_USER, currentUser });
},
setCurrentTeam: (currentTeam: ITeamSummary | undefined) => {
dispatch({ type: ACTIONS.SET_CURRENT_TEAM, currentTeam });
},
setConfig: (config: IConfig) => {
dispatch({ type: ACTIONS.SET_CONFIG, config });
},
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 });
},
setAPNsExpiry: (apnsExpiry: string) => {
dispatch({ type: ACTIONS.SET_APNS_EXPIRY, apnsExpiry });
},
setVppExpiry: (vppExpiry: string) => {
dispatch({
type: ACTIONS.SET_VPP_EXPIRY,
vppExpiry,
});
},
setSandboxExpiry: (sandboxExpiry: string) => {
dispatch({ type: ACTIONS.SET_SANDBOX_EXPIRY, sandboxExpiry });
},
setNoSandboxHosts: (noSandboxHosts: boolean) => {
dispatch({
type: ACTIONS.SET_NO_SANDBOX_HOSTS,
noSandboxHosts,
});
},
setFilteredHostsPath: (filteredHostsPath: string) => {
dispatch({ type: ACTIONS.SET_FILTERED_HOSTS_PATH, filteredHostsPath });
},
setFilteredSoftwarePath: (filteredSoftwarePath: string) => {
dispatch({
type: ACTIONS.SET_FILTERED_SOFTWARE_PATH,
filteredSoftwarePath,
});
},
setFilteredQueriesPath: (filteredQueriesPath: string) => {
dispatch({
type: ACTIONS.SET_FILTERED_QUERIES_PATH,
filteredQueriesPath,
});
},
setFilteredPoliciesPath: (filteredPoliciesPath: string) => {
dispatch({
type: ACTIONS.SET_FILTERED_POLICIES_PATH,
filteredPoliciesPath,
});
},
}),
[
state.abmExpiry,
state.apnsExpiry,
state.availableTeams,
state.userSettings,
state.config,
state.currentTeam,
state.currentUser,
state.enrollSecret,
state.filteredHostsPath,
state.filteredPoliciesPath,
state.filteredQueriesPath,
state.filteredSoftwarePath,
state.isAnyTeamAdmin,
state.isAnyTeamMaintainer,
state.isAnyTeamMaintainerOrTeamAdmin,
state.isAnyTeamObserverPlus,
state.isAndroidEnterpriseDeleted,
state.isAppleBmExpired,
state.isApplePnsExpired,
state.isFreeTier,
state.isGlobalAdmin,
state.isGlobalMaintainer,
state.isGlobalObserver,
state.isMacMdmEnabledAndConfigured,
state.isNoAccess,
state.isObserverPlus,
state.isOnGlobalTeam,
state.isOnlyObserver,
state.isPremiumTier,
state.isSandboxMode,
state.isTeamAdmin,
state.isTeamTechnician,
state.isAnyTeamTechnician,
state.isGlobalTechnician,
state.isTeamMaintainer,
state.isTeamMaintainerOrTeamAdmin,
state.isTeamObserver,
state.isVppExpired,
state.isWindowsMdmEnabledAndConfigured,
state.isAndroidMdmEnabledAndConfigured,
state.needsAbmTermsRenewal,
state.noSandboxHosts,
state.sandboxExpiry,
state.vppExpiry,
state.willAppleBmExpire,
state.willApplePnsExpire,
state.willVppExpire,
]
);
return <AppContext.Provider value={value}>{children}</AppContext.Provider>;
};
export default AppProvider;