diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_wait_for_fleet_server.ts b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_wait_for_fleet_server.ts index 4da59560e408e..7721025a75067 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_wait_for_fleet_server.ts +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_wait_for_fleet_server.ts @@ -6,9 +6,9 @@ */ import { i18n } from '@kbn/i18n'; -import { useEffect, useState } from 'react'; +import { useEffect } from 'react'; -import { sendGetFleetStatus, useStartServices } from '../../../hooks'; +import { useFleetStatus, useStartServices } from '../../../hooks'; const REFRESH_INTERVAL = 10000; @@ -17,26 +17,25 @@ const REFRESH_INTERVAL = 10000; * in the `missing_requirements` list. */ export const useWaitForFleetServer = () => { - const [isFleetServerReady, setIsFleetServerReady] = useState(false); + const fleetStatus = useFleetStatus(); const { notifications } = useStartServices(); + const isFleetServerReady = + fleetStatus.isReady && !fleetStatus.missingRequirements?.includes('fleet_server'); + useEffect(() => { let interval: ReturnType | null = null; if (!isFleetServerReady) { interval = setInterval(async () => { try { - const res = await sendGetFleetStatus(); - - if (res.error) { - throw res.error; - } - if (res.data?.isReady && !res.data?.missing_requirements?.includes('fleet_server')) { - setIsFleetServerReady(true); - + if (isFleetServerReady) { if (interval) { clearInterval(interval); } + } else { + fleetStatus.setForceDisplayInstructions(true); + fleetStatus.refresh(); } } catch (err) { notifications.toasts.addError(err, { @@ -55,7 +54,7 @@ export const useWaitForFleetServer = () => { }; return cleanup; - }, [notifications.toasts, isFleetServerReady]); + }, [notifications.toasts, isFleetServerReady, fleetStatus]); return { isFleetServerReady }; }; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/confirm_fleet_server_connection.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/confirm_fleet_server_connection.tsx index 15e8609191019..8111fd3f09ac6 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/confirm_fleet_server_connection.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/confirm_fleet_server_connection.tsx @@ -13,7 +13,7 @@ import { EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { useFlyoutContext } from '../../../hooks'; +import { useFleetStatus, useFlyoutContext } from '../../../hooks'; export function getConfirmFleetServerConnectionStep({ disabled, @@ -41,6 +41,12 @@ const ConfirmFleetServerConnectionStepContent: React.FunctionComponent<{ isFleetServerReady: boolean; }> = ({ isFleetServerReady }) => { const flyoutContext = useFlyoutContext(); + const fleetStatus = useFleetStatus(); + + const handleContinueClick = () => { + fleetStatus.forceDisplayInstructions = false; + flyoutContext.openEnrollmentFlyout(); + }; return isFleetServerReady ? ( <> @@ -53,7 +59,7 @@ const ConfirmFleetServerConnectionStepContent: React.FunctionComponent<{ - + { fleetStatus?.missingRequirements?.length === 1 && fleetStatus.missingRequirements[0] === 'fleet_server'; + const displayInstructions = + fleetStatus.forceDisplayInstructions || hasOnlyFleetServerMissingRequirement; + if ( !hasOnlyFleetServerMissingRequirement && fleetStatus.missingRequirements && @@ -86,7 +89,7 @@ export const AgentsApp: React.FunctionComponent = () => { return ; } - const rightColumn = hasOnlyFleetServerMissingRequirement ? ( + const rightColumn = displayInstructions ? ( <> @@ -114,7 +117,7 @@ export const AgentsApp: React.FunctionComponent = () => { {fleetServerModalVisible && ( )} - {hasOnlyFleetServerMissingRequirement ? ( + {displayInstructions ? ( ) : ( diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/instructions.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/instructions.tsx index 3619f6177cd53..97c0542ab2477 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/instructions.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/instructions.tsx @@ -15,6 +15,8 @@ import { FleetServerRequirementPage } from '../../applications/fleet/sections/ag import { AGENTS_PREFIX, FLEET_SERVER_PACKAGE, SO_SEARCH_LIMIT } from '../../constants'; +import { useFleetServerUnhealthy } from '../../applications/fleet/sections/agents/hooks/use_fleet_server_unhealthy'; + import { Loading } from '..'; import { policyHasFleetServer } from '../../services'; @@ -40,16 +42,11 @@ export const Instructions = (props: InstructionProps) => { refreshAgentPolicies, } = props; const fleetStatus = useFleetStatus(); - const REFRESH_INTERVAL = 10 * 1000; + const { isUnhealthy: isFleetServerUnhealthy } = useFleetServerUnhealthy(); useEffect(() => { - const interval = setInterval(() => { - fleetStatus.refresh(); - refreshAgentPolicies(); - }, REFRESH_INTERVAL); - - return () => clearInterval(interval); - }, [fleetStatus, REFRESH_INTERVAL, refreshAgentPolicies]); + refreshAgentPolicies(); + }, [refreshAgentPolicies]); const fleetServerAgentPolicies: string[] = useMemo( () => agentPolicies.filter((pol) => policyHasFleetServer(pol)).map((pol) => pol.id), @@ -67,30 +64,27 @@ export const Instructions = (props: InstructionProps) => { .join(' or ')}`, }); - const agentsWithFleetServers = agents?.items || []; + const fleetServers = agents?.items || []; - const hasFleetServerHosts = useMemo(() => { - return (settings?.fleet_server_hosts || []).length > 0; + const fleetServerHosts = useMemo(() => { + return settings?.fleet_server_hosts || []; }, [settings]); - const showAgentEnrollment = useMemo( - () => hasFleetServerHosts && fleetStatus.isReady && agentsWithFleetServers.length > 0, - [hasFleetServerHosts, fleetStatus.isReady, agentsWithFleetServers.length] - ); + if (isLoadingAgents || isLoadingAgentPolicies) return ; - const showFleetServerEnrollment = useMemo( - () => - !showAgentEnrollment || - (fleetStatus.missingRequirements ?? []).some((r) => r === FLEET_SERVER_PACKAGE), - [fleetStatus.missingRequirements, showAgentEnrollment] - ); + const hasNoFleetServerHost = fleetStatus.isReady && fleetServerHosts.length === 0; - const hasNoFleetServerHost = useMemo( - () => fleetStatus.isReady && (settings?.fleet_server_hosts || []).length === 0, - [fleetStatus.isReady, settings?.fleet_server_hosts] - ); + const showAgentEnrollment = + fleetStatus.isReady && + !isFleetServerUnhealthy && + fleetServers.length > 0 && + fleetServerHosts.length > 0; + + const showFleetServerEnrollment = + fleetServers.length === 0 || + isFleetServerUnhealthy || + (fleetStatus.missingRequirements ?? []).some((r) => r === FLEET_SERVER_PACKAGE); - if (isLoadingAgents || isLoadingAgentPolicies) return ; if (!isIntegrationFlow && showAgentEnrollment) { setSelectionType('radio'); } else { diff --git a/x-pack/plugins/fleet/public/hooks/use_fleet_status.tsx b/x-pack/plugins/fleet/public/hooks/use_fleet_status.tsx index b05df0c619e0a..85df40a31d801 100644 --- a/x-pack/plugins/fleet/public/hooks/use_fleet_status.tsx +++ b/x-pack/plugins/fleet/public/hooks/use_fleet_status.tsx @@ -23,17 +23,22 @@ interface FleetStatusState { interface FleetStatus extends FleetStatusState { refresh: () => Promise; + forceDisplayInstructions: boolean; + setForceDisplayInstructions: React.Dispatch; } const FleetStatusContext = React.createContext(undefined); export const FleetStatusProvider: React.FC = ({ children }) => { const config = useConfig(); + const [forceDisplayInstructions, setForceDisplayInstructions] = useState(false); + const [state, setState] = useState({ enabled: config.agents.enabled, isLoading: false, isReady: false, }); + const sendGetStatus = useCallback( async function sendGetStatus() { try { @@ -64,7 +69,9 @@ export const FleetStatusProvider: React.FC = ({ children }) => { const refresh = useCallback(() => sendGetStatus(), [sendGetStatus]); return ( - + {children} );