diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx index 93631f63d0e04..9af03e8916849 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useCallback, useEffect, useMemo, useState, Suspense } from 'react'; +import React, { useCallback, useEffect, useMemo, useState, Suspense, forwardRef } from 'react'; import { useRouteMatch } from 'react-router-dom'; import styled from 'styled-components'; import { i18n } from '@kbn/i18n'; @@ -20,6 +20,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiLink, + EuiPortal, EuiSpacer, EuiSteps, } from '@elastic/eui'; @@ -76,6 +77,8 @@ import { generateNewAgentPolicyWithDefaults } from '../../../../../../../common/ import { packageHasAtLeastOneSecret } from '../utils'; +import { useIntegrationsStateContext } from '../../../../../integrations/hooks'; + import { CreatePackagePolicySinglePageLayout, PostInstallAddAgentModal } from './components'; import { useDevToolsRequest, useOnSubmit, useSetupTechnology } from './hooks'; import { PostInstallCloudFormationModal } from './components/cloud_security_posture/post_install_cloud_formation_modal'; @@ -111,6 +114,9 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({ } = useConfig(); const hasFleetAddAgentsPrivileges = useAuthz().fleet.addAgents; const { params } = useRouteMatch(); + const { pkgkey: pkgKeyContext } = useIntegrationsStateContext(); + const pkgkey = params.pkgkey || pkgKeyContext; + const fleetStatus = useFleetStatus(); const { docLinks } = useStartServices(); const spaceSettings = useSpaceSettingsContext(); @@ -130,7 +136,7 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({ queryParamsPolicyId ? SelectedPolicyTab.EXISTING : SelectedPolicyTab.NEW ); - const { pkgName, pkgVersion } = splitPkgKey(params.pkgkey); + const { pkgName, pkgVersion } = splitPkgKey(pkgkey); // Fetch package info const { data: packageInfoData, @@ -230,7 +236,7 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({ const { cancelClickHandler, cancelUrl } = useCancelAddPackagePolicy({ from, - pkgkey: params.pkgkey, + pkgkey, agentPolicyId: agentPolicyIds[0], }); useEffect(() => { @@ -602,7 +608,12 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({ - + {/* Only show render button bar in portal when enableRouts is false*/} + {packageInfo && (formState === 'INVALID' || hasAgentPolicyError) ? ( diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/components/add_integration_button.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/components/add_integration_button.tsx index 8ff7f3e7d5ec3..7d60443e50af1 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/components/add_integration_button.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/components/add_integration_button.tsx @@ -14,7 +14,7 @@ interface AddIntegrationButtonProps { userCanInstallPackages?: boolean; missingSecurityConfiguration: boolean; packageName: string; - href: string; + href: string | undefined; onClick: Function; } diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/hooks/use_is_first_time_agent_user.ts b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/hooks/use_is_first_time_agent_user.ts index 86c5f544e7e6a..d57b512726449 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/hooks/use_is_first_time_agent_user.ts +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/hooks/use_is_first_time_agent_user.ts @@ -5,7 +5,6 @@ * 2.0. */ -import type { FleetAuthz } from '../../../../../../../../common'; import { FLEET_SERVER_PACKAGE, LEGACY_PACKAGE_POLICY_SAVED_OBJECT_TYPE, @@ -17,10 +16,8 @@ interface UseIsFirstTimeAgentUserResponse { isLoading?: boolean; } -export const useIsFirstTimeAgentUserQuery = ( - authzContext?: FleetAuthz -): UseIsFirstTimeAgentUserResponse => { - const authz = useAuthz() ?? authzContext; +export const useIsFirstTimeAgentUserQuery = (): UseIsFirstTimeAgentUserResponse => { + const authz = useAuthz(); const { data: packagePolicies, isLoading: areAgentPoliciesLoading, diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx index 825b870f48aca..effa47b277f74 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx @@ -130,7 +130,13 @@ function Breadcrumbs({ packageTitle }: { packageTitle: string }) { return null; } -export function Detail({ routesEnabled = true }: { routesEnabled?: boolean }) { +export function Detail({ + routesEnabled = true, + onAddElasticDefendClicked, +}: { + routesEnabled?: boolean; + onAddElasticDefendClicked?: () => void; +}) { const { getId: getAgentPolicyId } = useAgentPolicyContext(); const { getFromIntegrations, @@ -260,7 +266,7 @@ export function Detail({ routesEnabled = true }: { routesEnabled?: boolean }) { }, [packageInfoLatestPrereleaseData?.item.version]); const { isFirstTimeAgentUser = false, isLoading: firstTimeUserLoading } = - useIsFirstTimeAgentUserQuery(authz); + useIsFirstTimeAgentUserQuery(); const isGuidedOnboardingActive = useIsGuidedOnboardingActive(pkgName); // Refresh package info when status change @@ -403,66 +409,70 @@ export function Detail({ routesEnabled = true }: { routesEnabled?: boolean }) { [integrationInfo, isLoading, packageInfo, href, queryParams] ); - const handleAddIntegrationPolicyClick = useCallback( - (ev) => { - ev.preventDefault(); - // The object below, given to `createHref` is explicitly accessing keys of `location` in order - // to ensure that dependencies to this `useCallback` is set correctly (because `location` is mutable) - const currentPath = history.createHref({ - pathname, - search, - hash, - }); - - const defaultNavigateOptions: InstallPkgRouteOptions = getInstallPkgRouteOptions({ - agentPolicyId: agentPolicyIdFromContext, - currentPath, - integration, - isCloud, - isExperimentalAddIntegrationPageEnabled, - isFirstTimeAgentUser, - isGuidedOnboardingActive, - pkgkey, - }); - - /** Users from Security Solution onboarding page will have onboardingLink and onboardingAppId in the query params - ** to redirect back to the onboarding page after adding an integration - */ - const navigateOptions: InstallPkgRouteOptions = - onboardingAppId && onboardingLink - ? [ - defaultNavigateOptions[0], - { - ...defaultNavigateOptions[1], - state: { - ...(defaultNavigateOptions[1]?.state ?? {}), - onCancelNavigateTo: [onboardingAppId, { path: onboardingLink }], - onCancelUrl: onboardingLink, - onSaveNavigateTo: [onboardingAppId, { path: onboardingLink }], - }, - }, - ] - : defaultNavigateOptions; - - services.application.navigateToApp(...navigateOptions); - }, - [ - agentPolicyIdFromContext, - hash, - history, - integration, - isCloud, - isExperimentalAddIntegrationPageEnabled, - isFirstTimeAgentUser, - isGuidedOnboardingActive, - onboardingAppId, - onboardingLink, - pathname, - pkgkey, - search, - services.application, - ] - ); + // const handleAddIntegrationPolicyClick = useCallback( + // (ev) => { + // ev.preventDefault(); + // // The object below, given to `createHref` is explicitly accessing keys of `location` in order + // // to ensure that dependencies to this `useCallback` is set correctly (because `location` is mutable) + // const currentPath = history.createHref({ + // pathname, + // search, + // hash, + // }); + + // const defaultNavigateOptions: InstallPkgRouteOptions = getInstallPkgRouteOptions({ + // agentPolicyId: agentPolicyIdFromContext, + // currentPath, + // integration, + // isCloud, + // isExperimentalAddIntegrationPageEnabled, + // isFirstTimeAgentUser, + // isGuidedOnboardingActive, + // pkgkey, + // }); + + // /** Users from Security Solution onboarding page will have onboardingLink and onboardingAppId in the query params + // ** to redirect back to the onboarding page after adding an integration + // */ + // const navigateOptions: InstallPkgRouteOptions = + // onboardingAppId && onboardingLink + // ? [ + // defaultNavigateOptions[0], + // { + // ...defaultNavigateOptions[1], + // state: { + // ...(defaultNavigateOptions[1]?.state ?? {}), + // onCancelNavigateTo: [onboardingAppId, { path: onboardingLink }], + // onCancelUrl: onboardingLink, + // onSaveNavigateTo: [onboardingAppId, { path: onboardingLink }], + // }, + // }, + // ] + // : defaultNavigateOptions; + + // services.application.navigateToApp(...navigateOptions); + // }, + // [ + // agentPolicyIdFromContext, + // hash, + // history, + // integration, + // isCloud, + // isExperimentalAddIntegrationPageEnabled, + // isFirstTimeAgentUser, + // isGuidedOnboardingActive, + // onboardingAppId, + // onboardingLink, + // pathname, + // pkgkey, + // search, + // services.application, + // ] + // ); + + const handleAddIntegrationPolicyClick = useCallback(() => { + !routesEnabled && onAddElasticDefendClicked?.(); + }, [routesEnabled, onAddElasticDefendClicked]); const showVersionSelect = useMemo( () => @@ -566,13 +576,14 @@ export function Detail({ routesEnabled = true }: { routesEnabled?: boolean }) { > { export const UIExtensionsContextProvider = () => { return import('./hooks/use_ui_extension'); }; + +export const CreatePackagePolicyPage = () => { + return import('./applications/fleet/sections/agent_policy/create_package_policy_page'); +}; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/integration_card_grid_tabs.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/integration_card_grid_tabs.tsx index 2b79e691c74ca..dc2f204c87d8f 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/integration_card_grid_tabs.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/integration_card_grid_tabs.tsx @@ -94,11 +94,16 @@ const UIExtensionsContextProvider = lazy(async () => ({ .then((pkg) => pkg.UIExtensionsContextProvider), })); +const CreatePackagePolicyPage = lazy(async () => ({ + default: await import('@kbn/fleet-plugin/public') + .then((module) => module.CreatePackagePolicyPage()) + .then((pkg) => pkg.CreatePackagePolicyPage), +})); + export const IntegrationsCardGridTabsComponent = React.memo( ({ installedIntegrationsCount, isAgentRequired, useAvailablePackages }) => { const { spaceId } = useOnboardingContext(); const startServices = useKibana().services; - const { state: routerState } = useLocation(); const scrollElement = useRef(null); const [toggleIdSelected, setSelectedTabIdToStorage] = useStoredIntegrationTabId( spaceId, @@ -117,9 +122,19 @@ export const IntegrationsCardGridTabsComponent = React.memo setIsModalVisible(false); - const showModal = () => setIsModalVisible(true); + const [modalView, setModalView] = useState<'overview' | 'configure-integration' | 'add-agent'>( + 'overview' + ); + const onAddElasticDefendClicked = useCallback(() => { + setModalView('configure-integration'); + }, []); + const closeModal = useCallback(() => { + setIsModalVisible(false); + setModalView('overview'); + }, []); + const showModal = useCallback(() => setIsModalVisible(true), []); + const ref = useRef(null); + let bottomBar; const modalTitleId = useGeneratedHtmlId(); const { filteredCards, @@ -133,7 +148,7 @@ export const IntegrationsCardGridTabsComponent = React.memo INTEGRATION_TABS_BY_ID[toggleIdSelected], [toggleIdSelected]); - + console.log('=ref===', ref); const onSearchTermChanged = useCallback( (searchQuery: string) => { setSearchTerm(searchQuery); @@ -172,7 +187,6 @@ export const IntegrationsCardGridTabsComponent = React.memo - - Modal title - + {modalView !== 'overview' && ( + "Step indicator placeholder" + )} - + {modalView === 'overview' && ( + + )} + {modalView === 'configure-integration' && }