diff --git a/frontend/interfaces/platform.ts b/frontend/interfaces/platform.ts index 013f338737..384e0e87d6 100644 --- a/frontend/interfaces/platform.ts +++ b/frontend/interfaces/platform.ts @@ -215,3 +215,9 @@ export const SETUP_EXPERIENCE_PLATFORMS = [ ] as const; export type SetupExperiencePlatform = typeof SETUP_EXPERIENCE_PLATFORMS[number]; + +export const isSetupExperiencePlatform = ( + s: string | undefined +): s is SetupExperiencePlatform => { + return SETUP_EXPERIENCE_PLATFORMS.includes(s as SetupExperiencePlatform); +}; diff --git a/frontend/pages/ManageControlsPage/SetupExperience/SetupExperience.tsx b/frontend/pages/ManageControlsPage/SetupExperience/SetupExperience.tsx index 41e9e6f323..3fecfd98de 100644 --- a/frontend/pages/ManageControlsPage/SetupExperience/SetupExperience.tsx +++ b/frontend/pages/ManageControlsPage/SetupExperience/SetupExperience.tsx @@ -23,7 +23,7 @@ const SetupExperience = ({ router, teamIdForApi, }: ISetupExperienceProps) => { - const { section } = params; + const { section, platform: urlPlatformParam } = params; const { isPremiumTier } = useContext(AppContext); // Not premium shows premium message @@ -41,6 +41,14 @@ const SetupExperience = ({ SETUP_EXPERIENCE_NAV_ITEMS.find((item) => item.urlSection === section) ?? DEFAULT_SETTINGS_SECTION; + if ( + currentFormSection.urlSection !== "install-software" && + urlPlatformParam + ) { + router.replace( + currentFormSection.path + queryString // current card doesn't support platforms yet + ); + } const CurrentCard = currentFormSection.Card; return ( @@ -58,6 +66,7 @@ const SetupExperience = ({ key={teamIdForApi} currentTeamId={teamIdForApi} router={router} + urlPlatformParam={urlPlatformParam} /> } /> diff --git a/frontend/pages/ManageControlsPage/SetupExperience/SetupExperienceNavItems.tsx b/frontend/pages/ManageControlsPage/SetupExperience/SetupExperienceNavItems.tsx index 79047de0d9..2a30d8a784 100644 --- a/frontend/pages/ManageControlsPage/SetupExperience/SetupExperienceNavItems.tsx +++ b/frontend/pages/ManageControlsPage/SetupExperience/SetupExperienceNavItems.tsx @@ -13,6 +13,7 @@ import RunScript from "./cards/RunScript"; export interface ISetupExperienceCardProps { currentTeamId: number; router: InjectedRouter; + urlPlatformParam?: string; // not yet guaranteed to be a valid platform } const SETUP_EXPERIENCE_NAV_ITEMS: ISideNavItem[] = [ @@ -31,7 +32,7 @@ const SETUP_EXPERIENCE_NAV_ITEMS: ISideNavItem[] = [ { title: "3. Install software", urlSection: "install-software", - path: PATHS.CONTROLS_INSTALL_SOFTWARE, + path: PATHS.CONTROLS_INSTALL_SOFTWARE("macos"), Card: InstallSoftware, }, { diff --git a/frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/InstallSoftware.tsx b/frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/InstallSoftware.tsx index ea36ceb6a5..daec627f13 100644 --- a/frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/InstallSoftware.tsx +++ b/frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/InstallSoftware.tsx @@ -3,16 +3,21 @@ import { useQuery } from "react-query"; import { AxiosError } from "axios"; import { Tab, TabList, TabPanel, Tabs } from "react-tabs"; +import PATHS from "router/paths"; + import mdmAPI, { IGetSetupExperienceSoftwareResponse, } from "services/entities/mdm"; import configAPI from "services/entities/config"; import teamsAPI, { ILoadTeamResponse } from "services/entities/teams"; import { ISoftwareTitle } from "interfaces/software"; -import { DEFAULT_USE_QUERY_OPTIONS, SUPPORT_LINK } from "utilities/constants"; +import { DEFAULT_USE_QUERY_OPTIONS } from "utilities/constants"; import { IConfig } from "interfaces/config"; import { API_NO_TEAM_ID, ITeamConfig } from "interfaces/team"; -import { SetupExperiencePlatform } from "interfaces/platform"; +import { + isSetupExperiencePlatform, + SetupExperiencePlatform, +} from "interfaces/platform"; import SectionHeader from "components/SectionHeader"; import DataError from "components/DataError"; @@ -34,23 +39,30 @@ const baseClass = "install-software"; // available for install so we can correctly display the selected count. const PER_PAGE_SIZE = 3000; -const DEFAULT_PLATFORM: SetupExperiencePlatform = "macos"; - export const PLATFORM_BY_INDEX: SetupExperiencePlatform[] = [ "macos", "windows", "linux", ]; +export interface InstallSoftwareLocation { + search: string; + pathname: string; + query: { + team_id?: string; + }; +} const InstallSoftware = ({ currentTeamId, router, + urlPlatformParam, }: ISetupExperienceCardProps) => { + const isValidPlatform = isSetupExperiencePlatform(urlPlatformParam); + + // all uses of selectedPlatform are gated by above boolean + const selectedPlatform = urlPlatformParam as SetupExperiencePlatform; + const [showSelectSoftwareModal, setShowSelectSoftwareModal] = useState(false); - const [ - selectedPlatform, - setSelectedPlatform, - ] = useState(DEFAULT_PLATFORM); const { data: softwareTitles, @@ -72,6 +84,7 @@ const InstallSoftware = ({ { ...DEFAULT_USE_QUERY_OPTIONS, select: (res) => res.software_titles, + enabled: isValidPlatform, } ); @@ -80,6 +93,7 @@ const InstallSoftware = ({ Error >(["config", currentTeamId], () => configAPI.loadAll(), { ...DEFAULT_USE_QUERY_OPTIONS, + enabled: isValidPlatform, }); const { data: teamConfig, isLoading: isLoadingTeamConfig } = useQuery< @@ -88,19 +102,33 @@ const InstallSoftware = ({ ITeamConfig >(["team", currentTeamId], () => teamsAPI.load(currentTeamId), { ...DEFAULT_USE_QUERY_OPTIONS, - enabled: currentTeamId !== API_NO_TEAM_ID, + enabled: isValidPlatform && currentTeamId !== API_NO_TEAM_ID, select: (res) => res.team, }); + const handleTabChange = useCallback( + (index: number) => { + const newPlatform = PLATFORM_BY_INDEX[index]; + router.push( + PATHS.CONTROLS_INSTALL_SOFTWARE(newPlatform).concat( + location?.search ?? "" + ) + ); + }, + [router] + ); + + if (!isValidPlatform) { + router.replace( + PATHS.CONTROLS_INSTALL_SOFTWARE("macos").concat(location?.search ?? "") + ); + } + const onSave = async () => { setShowSelectSoftwareModal(false); refetchSoftwareTitles(); }; - const handleTabChange = useCallback((index: number) => { - setSelectedPlatform(PLATFORM_BY_INDEX[index]); - }, []); - const hasManualAgentInstall = getManualAgentInstallSetting( currentTeamId, globalConfig, diff --git a/frontend/router/index.tsx b/frontend/router/index.tsx index d5a04c3222..521978fed7 100644 --- a/frontend/router/index.tsx +++ b/frontend/router/index.tsx @@ -288,16 +288,22 @@ const routes = ( + + + + - + `${URL_PREFIX}/controls/setup-experience/install-software/${platform}`, CONTROLS_RUN_SCRIPT: `${URL_PREFIX}/controls/setup-experience/run-script`, CONTROLS_SCRIPTS: `${URL_PREFIX}/controls/scripts`, CONTROLS_SCRIPTS_LIBRARY: `${URL_PREFIX}/controls/scripts/library`,