diff --git a/frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareFleetMaintained/FleetMaintainedAppDetailsPage/FleetAppDetailsForm/FleetAppDetailsForm.tsx b/frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareFleetMaintained/FleetMaintainedAppDetailsPage/FleetAppDetailsForm/FleetAppDetailsForm.tsx index 4174be5461b..1148d03cc52 100644 --- a/frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareFleetMaintained/FleetMaintainedAppDetailsPage/FleetAppDetailsForm/FleetAppDetailsForm.tsx +++ b/frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareFleetMaintained/FleetMaintainedAppDetailsPage/FleetAppDetailsForm/FleetAppDetailsForm.tsx @@ -1,28 +1,16 @@ -import React, { useContext, useState } from "react"; -import { AppContext } from "context/app"; +/** FleetAppDetailsForm is a separate component remnant of when we had advanced options on add <4.83 */ -import { ILabelSummary } from "interfaces/label"; +import React from "react"; import { SoftwareCategory } from "interfaces/software"; -import { - CUSTOM_TARGET_OPTIONS, - generateHelpText, -} from "pages/SoftwarePage/helpers"; import { getPathWithQueryParams } from "utilities/url"; import paths from "router/paths"; -import RevealButton from "components/buttons/RevealButton"; import Button from "components/buttons/Button"; -import Card from "components/Card"; -import SoftwareOptionsSelector from "pages/SoftwarePage/components/forms/SoftwareOptionsSelector"; -import TargetLabelSelector from "components/TargetLabelSelector"; import TooltipWrapper from "components/TooltipWrapper"; import CustomLink from "components/CustomLink"; -import AdvancedOptionsFields from "pages/SoftwarePage/components/forms/AdvancedOptionsFields"; import GitOpsModeTooltipWrapper from "components/GitOpsModeTooltipWrapper"; -import { generateFormValidation } from "./helpers"; - const baseClass = "fleet-app-details-form"; export const softwareAlreadyAddedTipContent = ( @@ -69,42 +57,27 @@ export interface IFormValidation { } interface IFleetAppDetailsFormProps { - labels: ILabelSummary[] | null; categories?: SoftwareCategory[] | null; - name: string; defaultInstallScript: string; defaultPostInstallScript: string; defaultUninstallScript: string; teamId?: string; - showSchemaButton: boolean; - onClickShowSchema: () => void; - onClickPreviewEndUserExperience: () => void; onCancel: () => void; onSubmit: (formData: IFleetMaintainedAppFormData) => void; softwareTitleId?: number; } const FleetAppDetailsForm = ({ - labels, categories, - name: appName, defaultInstallScript, defaultPostInstallScript, defaultUninstallScript, teamId, - showSchemaButton, - onClickShowSchema, - onClickPreviewEndUserExperience, onCancel, onSubmit, softwareTitleId, }: IFleetAppDetailsFormProps) => { - const gitOpsModeEnabled = useContext(AppContext).config?.gitops - .gitops_mode_enabled; - - const [showAdvancedOptions, setShowAdvancedOptions] = useState(false); - - const [formData, setFormData] = useState({ + const formData: IFleetMaintainedAppFormData = { selfService: false, automaticInstall: false, preInstallQuery: "", @@ -115,96 +88,6 @@ const FleetAppDetailsForm = ({ customTarget: "labelsIncludeAny", labelTargets: {}, categories: categories || [], - }); - const [formValidation, setFormValidation] = useState({ - isValid: true, - preInstallQuery: { isValid: false }, - }); - - const onChangePreInstallQuery = (value?: string) => { - const newData = { ...formData, preInstallQuery: value }; - setFormData(newData); - setFormValidation(generateFormValidation(newData)); - }; - - const onChangeInstallScript = (value: string) => { - const newData = { ...formData, installScript: value }; - setFormData(newData); - setFormValidation(generateFormValidation(newData)); - }; - - const onChangePostInstallScript = (value?: string) => { - const newData = { ...formData, postInstallScript: value }; - setFormData(newData); - setFormValidation(generateFormValidation(newData)); - }; - - const onChangeUninstallScript = (value?: string) => { - const newData = { ...formData, uninstallScript: value }; - setFormData(newData); - setFormValidation(generateFormValidation(newData)); - }; - - const onToggleSelfService = () => { - const newData = { ...formData, selfService: !formData.selfService }; - setFormData(newData); - setFormValidation(generateFormValidation(newData)); - }; - - const onToggleAutomaticInstall = () => { - const newData = { - ...formData, - automaticInstall: !formData.automaticInstall, - }; - setFormData(newData); - }; - - const onSelectTargetType = (value: string) => { - const newData = { ...formData, targetType: value }; - setFormData(newData); - setFormValidation(generateFormValidation(newData)); - }; - - const onSelectCustomTargetOption = (value: string) => { - const newData = { ...formData, customTarget: value }; - setFormData(newData); - }; - - const onSelectLabel = ({ name, value }: { name: string; value: boolean }) => { - const newData = { - ...formData, - labelTargets: { ...formData.labelTargets, [name]: value }, - }; - setFormData(newData); - setFormValidation(generateFormValidation(newData)); - }; - - const onSelectCategory = ({ - name, - value, - }: { - name: string; - value: boolean; - }) => { - let newCategories: string[]; - - if (value) { - // Add the name if not already present - newCategories = formData.categories.includes(name) - ? formData.categories - : [...formData.categories, name]; - } else { - // Remove the name if present - newCategories = formData.categories.filter((cat) => cat !== name); - } - - const newData = { - ...formData, - categories: newCategories, - }; - - setFormData(newData); - setFormValidation(generateFormValidation(newData)); }; const onSubmitForm = (evt: React.FormEvent) => { @@ -212,81 +95,11 @@ const FleetAppDetailsForm = ({ onSubmit(formData); }; - const gitOpsModeDisabledClass = gitOpsModeEnabled - ? "form-fields--disabled" - : ""; const isSoftwareAlreadyAdded = !!softwareTitleId; - const isSubmitDisabled = isSoftwareAlreadyAdded; // Allows saving invalid SQL - - // Define errors separately so AdvancedOptionsFields can memoize effectively - const errors = { - preInstallQuery: formValidation.preInstallQuery?.message, - }; + const isSubmitDisabled = isSoftwareAlreadyAdded; return ( -
-
- - - - - - -
-
- setShowAdvancedOptions(!showAdvancedOptions)} - disabled={isSoftwareAlreadyAdded} - /> - {showAdvancedOptions && ( - - )} -
+
( diff --git a/frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareFleetMaintained/FleetMaintainedAppDetailsPage/FleetMaintainedAppDetailsPage.tsx b/frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareFleetMaintained/FleetMaintainedAppDetailsPage/FleetMaintainedAppDetailsPage.tsx index 129a33ac3c8..4e04d9c6a8e 100644 --- a/frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareFleetMaintained/FleetMaintainedAppDetailsPage/FleetMaintainedAppDetailsPage.tsx +++ b/frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareFleetMaintained/FleetMaintainedAppDetailsPage/FleetMaintainedAppDetailsPage.tsx @@ -9,27 +9,21 @@ import PATHS from "router/paths"; import { getPathWithQueryParams } from "utilities/url"; import { DEFAULT_USE_QUERY_OPTIONS } from "utilities/constants"; import softwareAPI from "services/entities/software"; -import labelsAPI, { getCustomLabels } from "services/entities/labels"; -import { QueryContext } from "context/query"; import { AppContext } from "context/app"; import { NotificationContext } from "context/notification"; import { Platform, PLATFORM_DISPLAY_NAMES } from "interfaces/platform"; -import { ILabelSummary } from "interfaces/label"; -import useToggleSidePanel from "hooks/useToggleSidePanel"; import SidePanelPage from "components/SidePanelPage"; import BackButton from "components/BackButton"; import MainContent from "components/MainContent"; import Spinner from "components/Spinner"; import DataError from "components/DataError"; -import SidePanelContent from "components/SidePanelContent"; -import QuerySidePanel from "components/side_panels/QuerySidePanel"; import PremiumFeatureMessage from "components/PremiumFeatureMessage"; import Card from "components/Card"; import SoftwareIcon from "pages/SoftwarePage/components/icons/SoftwareIcon"; import Button from "components/buttons/Button"; import Icon from "components/Icon"; -import CategoriesEndUserExperienceModal from "pages/SoftwarePage/components/modals/CategoriesEndUserExperienceModal"; +import PageDescription from "components/PageDescription"; import FleetAppDetailsForm from "./FleetAppDetailsForm"; import { IFleetMaintainedAppFormData } from "./FleetAppDetailsForm/FleetAppDetailsForm"; @@ -142,19 +136,11 @@ const FleetMaintainedAppDetailsPage = ({ const handlePageError = useErrorHandler(); const { isPremiumTier } = useContext(AppContext); - const { selectedOsqueryTable, setSelectedOsqueryTable } = useContext( - QueryContext - ); - const { isSidePanelOpen, setSidePanelOpen } = useToggleSidePanel(false); const [ showAddFleetAppSoftwareModal, setShowAddFleetAppSoftwareModal, ] = useState(false); const [showAppDetailsModal, setShowAppDetailsModal] = useState(false); - const [ - showPreviewEndUserExperience, - setShowPreviewEndUserExperience, - ] = useState(false); const { data: fleetApp, @@ -172,36 +158,10 @@ const FleetMaintainedAppDetailsPage = ({ } ); - const { - data: labels, - isLoading: isLoadingLabels, - isError: isErrorLabels, - } = useQuery( - ["custom_labels"], - () => - labelsAPI - .summary(parseInt(teamId || "0", 10)) - .then((res) => getCustomLabels(res.labels)), - - { - ...DEFAULT_USE_QUERY_OPTIONS, - enabled: isPremiumTier, - staleTime: 10000, - } - ); - - const onOsqueryTableSelect = (tableName: string) => { - setSelectedOsqueryTable(tableName); - }; - const onClickShowAppDetails = () => { setShowAppDetailsModal(true); }; - const onClickPreviewEndUserExperience = () => { - setShowPreviewEndUserExperience(!showPreviewEndUserExperience); - }; - const backToAddSoftwareUrl = getPathWithQueryParams( PATHS.SOFTWARE_ADD_FLEET_MAINTAINED, { fleet_id: teamId } @@ -254,11 +214,11 @@ const FleetMaintainedAppDetailsPage = ({ return ; } - if (isLoadingFleetApp || isLoadingLabels) { + if (isLoadingFleetApp) { return ; } - if (isErrorFleetApp || isErrorLabels) { + if (isErrorFleetApp) { return ; } @@ -271,6 +231,10 @@ const FleetMaintainedAppDetailsPage = ({ className={`${baseClass}__back-to-add-software`} />

{fleetApp.name}

+
setSidePanelOpen(true)} onCancel={onCancel} onSubmit={onSubmit} softwareTitleId={fleetApp.software_title_id} - onClickPreviewEndUserExperience={onClickPreviewEndUserExperience} />
- {showPreviewEndUserExperience && ( - - )} ); } @@ -312,16 +266,6 @@ const FleetMaintainedAppDetailsPage = ({ <>{renderContent()} - {isPremiumTier && fleetApp && isSidePanelOpen && ( - - setSidePanelOpen(false)} - /> - - )} {showAddFleetAppSoftwareModal && } {showAppDetailsModal && fleetApp && ( ( {showOptionsTargetsSelectors && (
- {isEditingSoftware ? ( - renderSoftwareOptionsSelector() - ) : ( - - {renderSoftwareOptionsSelector()} - - )} - {isEditingSoftware ? ( - renderTargetLabelSelector() - ) : ( - - {renderTargetLabelSelector()} - - )} + {renderSoftwareOptionsSelector()} + {renderTargetLabelSelector()}
)}
diff --git a/frontend/pages/SoftwarePage/components/forms/SoftwareAndroidForm/SoftwareAndroidForm.tsx b/frontend/pages/SoftwarePage/components/forms/SoftwareAndroidForm/SoftwareAndroidForm.tsx index 306a52b797d..8d4c19090a5 100644 --- a/frontend/pages/SoftwarePage/components/forms/SoftwareAndroidForm/SoftwareAndroidForm.tsx +++ b/frontend/pages/SoftwarePage/components/forms/SoftwareAndroidForm/SoftwareAndroidForm.tsx @@ -22,6 +22,7 @@ import { } from "pages/SoftwarePage/helpers"; import generateFormValidation from "./helpers"; +import { AndroidOptionsDescription } from "../SoftwareOptionsSelector/SoftwareOptionsSelector"; const baseClass = "software-android-form"; @@ -148,43 +149,35 @@ const SoftwareAndroidForm = ({ // Add Android form return ( -
- - The ID at the end of the app's{" "} - {" "} - E.g. "com.android.chrome" from - "https://play.google.com/store/apps/details?id=com.android.chrome" - - } - onChange={onInputChange} - name="applicationID" - value={formData.applicationID} - parseTarget - disabled={gitOpsModeEnabled} // TODO: Confirm GitOps behavior - /> -
- - - + <> +
+ + The ID at the end of the app's{" "} + {" "} + E.g. "com.android.chrome" from + "https://play.google.com/store/apps/details?id=com.android.chrome" + + } + onChange={onInputChange} + name="applicationID" + value={formData.applicationID} + parseTarget + disabled={gitOpsModeEnabled} // TODO: Confirm GitOps behavior + />
-
+
+ +
+ ); }; diff --git a/frontend/pages/SoftwarePage/components/forms/SoftwareOptionsSelector/SoftwareOptionsSelector.tsx b/frontend/pages/SoftwarePage/components/forms/SoftwareOptionsSelector/SoftwareOptionsSelector.tsx index 50e05ef41a9..b5efabe2156 100644 --- a/frontend/pages/SoftwarePage/components/forms/SoftwareOptionsSelector/SoftwareOptionsSelector.tsx +++ b/frontend/pages/SoftwarePage/components/forms/SoftwareOptionsSelector/SoftwareOptionsSelector.tsx @@ -29,6 +29,19 @@ interface ICategoriesSelector { onClickPreviewEndUserExperience: () => void; } +export const AndroidOptionsDescription = () => ( +

+ Currently, Android apps can only be added as self-service and the end user + can install them from the Play Store in their work profile. + Additionally, you can install it when hosts enroll on the{" "} + {" "} + page. +

+); + const CategoriesSelector = ({ onSelectCategory, selectedCategories, @@ -159,19 +172,7 @@ const SoftwareOptionsSelector = ({ const renderOptionsDescription = () => { if (isPlatformAndroid) { - return ( -

- Currently, Android apps can only be added as self-service and the end - user can install them from the Play Store in their - work profile. Additionally, you can install it when hosts enroll on - the{" "} - {" "} - page. -

- ); + return ; } // Render unavailable description for iOS or iPadOS add software form only return isPlatformIosOrIpados && !isEditingSoftware ? ( diff --git a/frontend/pages/SoftwarePage/components/forms/SoftwareVppForm/SoftwareVppForm.tsx b/frontend/pages/SoftwarePage/components/forms/SoftwareVppForm/SoftwareVppForm.tsx index 5c346c8c740..2a1653090b5 100644 --- a/frontend/pages/SoftwarePage/components/forms/SoftwareVppForm/SoftwareVppForm.tsx +++ b/frontend/pages/SoftwarePage/components/forms/SoftwareVppForm/SoftwareVppForm.tsx @@ -8,7 +8,6 @@ import { PLATFORM_DISPLAY_NAMES } from "interfaces/platform"; import { IAppStoreApp, isIpadOrIphoneSoftware } from "interfaces/software"; import { IVppApp } from "services/entities/mdm_apple"; -import Card from "components/Card"; import CustomLink from "components/CustomLink"; import Radio from "components/forms/fields/Radio"; import Button from "components/buttons/Button"; @@ -298,6 +297,7 @@ const SoftwareVppForm = ({ } // Add VPP form + // 4.83+ has no additional options to select beyond the app if (vppApps) { return (
@@ -311,43 +311,6 @@ const SoftwareVppForm = ({ apps, head to{" "}
-
- - - onClickPreviewEndUserExperience( - isIpadOrIphoneSoftware(formData.selectedApp?.platform || "") - ) - } - /> - - - - -
); }