Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,19 @@ import { Redirect, useRouteMatch, Switch, Route, useHistory, useLocation } from
import { i18n } from '@kbn/i18n';
import { FormattedMessage, FormattedDate } from '@kbn/i18n/react';
import {
EuiButtonEmpty,
EuiDescriptionList,
EuiDescriptionListDescription,
EuiDescriptionListTitle,
EuiFlexGroup,
EuiFlexItem,
EuiI18nNumber,
EuiIconTip,
EuiTitle,
EuiText,
EuiLink,
EuiPortal,
EuiSpacer,
EuiButtonEmpty,
EuiI18nNumber,
EuiDescriptionList,
EuiDescriptionListTitle,
EuiDescriptionListDescription,
EuiText,
EuiTitle,
} from '@elastic/eui';
import type { Props as EuiTabProps } from '@elastic/eui/src/components/tabs/tab';
import styled from 'styled-components';
Expand All @@ -36,7 +38,7 @@ import {
useFleetStatus,
useIntraAppState,
} from '../../../hooks';
import { Loading, Error } from '../../../components';
import { Loading, Error, AgentEnrollmentFlyout, AddAgentHelpPopover } from '../../../components';
import { WithHeaderLayout } from '../../../layouts';
import { LinkedAgentCount, AgentPolicyActionMenu } from '../components';

Expand All @@ -58,16 +60,24 @@ export const AgentPolicyDetailsPage: React.FunctionComponent = () => {
const agentPolicyRequest = useGetOneAgentPolicy(policyId);
const agentPolicy = agentPolicyRequest.data ? agentPolicyRequest.data.item : null;
const { isLoading, error, sendRequest: refreshAgentPolicy } = agentPolicyRequest;
const queryParams = new URLSearchParams(useLocation().search);
const openEnrollmentFlyoutOpenByDefault = queryParams.get('openEnrollmentFlyout') === 'true';
const openAddAgentHelpPopoverOpenByDefault = queryParams.get('showAddAgentHelp') === 'true';
const [redirectToAgentPolicyList] = useState<boolean>(false);
const [isEnrollmentFlyoutOpen, setIsEnrollmentFlyoutOpen] = useState<boolean>(
openEnrollmentFlyoutOpenByDefault
);
const [isAddAgentHelpPopoverOpen, setIsAddAgentHelpPopoverOpen] = useState<boolean>(
openAddAgentHelpPopoverOpenByDefault
);
const agentStatusRequest = useGetAgentStatus(policyId);
const { refreshAgentStatus } = agentStatusRequest;
const {
application: { navigateToApp },
} = useStartServices();
const routeState = useIntraAppState<AgentPolicyDetailsDeployAgentAction>();
const agentStatus = agentStatusRequest.data?.results;
const queryParams = new URLSearchParams(useLocation().search);
const openEnrollmentFlyoutOpenByDefault = queryParams.get('openEnrollmentFlyout') === 'true';

const { isReady: isFleetReady } = useFleetStatus();

const headerLeftContent = useMemo(
Expand Down Expand Up @@ -138,6 +148,25 @@ export const AgentPolicyDetailsPage: React.FunctionComponent = () => {
[getHref, isLoading, agentPolicy, policyId]
);

const onCancelEnrollment = useMemo(() => {
if (routeState && routeState.onDoneNavigateTo && isFleetReady) {
const [appId, options] = routeState.onDoneNavigateTo;
return () => navigateToApp(appId, options);
}

return undefined;
}, [isFleetReady, navigateToApp, routeState]);

const addAgentLink = (
<EuiLink
onClick={() => {
setIsAddAgentHelpPopoverOpen(false);
setIsEnrollmentFlyoutOpen(true);
}}
>
<FormattedMessage id="xpack.fleet.policyDetails.addAgentButton" defaultMessage="Add agent" />
</EuiLink>
);
const headerRightContent = useMemo(
() =>
agentPolicy ? (
Expand Down Expand Up @@ -168,15 +197,25 @@ export const AgentPolicyDetailsPage: React.FunctionComponent = () => {
{ isDivider: true },
{
label: i18n.translate('xpack.fleet.policyDetails.summary.usedBy', {
defaultMessage: 'Used by',
defaultMessage: 'Agents',
}),
content: (
<LinkedAgentCount
count={(agentStatus && agentStatus.total) || 0}
agentPolicyId={(agentPolicy && agentPolicy.id) || ''}
showAgentText
/>
),
content:
agentStatus && agentStatus!.total ? (
<LinkedAgentCount
count={agentStatus.total}
agentPolicyId={(agentPolicy && agentPolicy.id) || ''}
showAgentText
/>
) : (
<AddAgentHelpPopover
button={addAgentLink}
isOpen={isAddAgentHelpPopoverOpen}
offset={15}
closePopover={() => {
setIsAddAgentHelpPopoverOpen(false);
}}
/>
),
},
{ isDivider: true },
{
Expand All @@ -203,16 +242,7 @@ export const AgentPolicyDetailsPage: React.FunctionComponent = () => {
onCopySuccess={(newAgentPolicy: AgentPolicy) => {
history.push(getPath('policy_details', { policyId: newAgentPolicy.id }));
}}
enrollmentFlyoutOpenByDefault={openEnrollmentFlyoutOpenByDefault}
onCancelEnrollment={
routeState && routeState.onDoneNavigateTo && isFleetReady
? () =>
navigateToApp(
routeState.onDoneNavigateTo![0],
routeState.onDoneNavigateTo![1]
)
: undefined
}
onCancelEnrollment={onCancelEnrollment}
/>
),
},
Expand All @@ -237,7 +267,7 @@ export const AgentPolicyDetailsPage: React.FunctionComponent = () => {
</EuiFlexGroup>
) : undefined,
/* eslint-disable-next-line react-hooks/exhaustive-deps */
[agentPolicy, policyId, agentStatus]
[agentPolicy, policyId, agentStatus, isAddAgentHelpPopoverOpen]
);

const headerTabs = useMemo(() => {
Expand Down Expand Up @@ -303,8 +333,28 @@ export const AgentPolicyDetailsPage: React.FunctionComponent = () => {
);
}

return <AgentPolicyDetailsContent agentPolicy={agentPolicy} />;
}, [agentPolicy, policyId, error, isLoading, redirectToAgentPolicyList]);
return (
<>
{isEnrollmentFlyoutOpen && (
<EuiPortal>
<AgentEnrollmentFlyout
agentPolicy={agentPolicy}
onClose={onCancelEnrollment || (() => setIsEnrollmentFlyoutOpen(false))}
/>
</EuiPortal>
)}
<AgentPolicyDetailsContent agentPolicy={agentPolicy} />;
</>
);
}, [
redirectToAgentPolicyList,
isLoading,
error,
agentPolicy,
isEnrollmentFlyoutOpen,
onCancelEnrollment,
policyId,
]);

return (
<AgentPolicyRefreshContext.Provider value={{ refresh: refreshAgentPolicy }}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,20 @@ import { createIntegrationsTestRendererMock } from '../../../../../../../../mock

import { PackagePolicyAgentsCell } from './package_policy_agents_cell';

function renderCell({ agentCount = 0, agentPolicyId = '123', onAddAgent = () => {} }) {
function renderCell({
agentCount = 0,
agentPolicyId = '123',
onAddAgent = () => {},
hasHelpPopover = false,
}) {
const renderer = createIntegrationsTestRendererMock();

return renderer.render(
<PackagePolicyAgentsCell
agentCount={agentCount}
agentPolicyId={agentPolicyId}
onAddAgent={onAddAgent}
hasHelpPopover={hasHelpPopover}
/>
);
}
Expand All @@ -40,4 +46,25 @@ describe('PackagePolicyAgentsCell', () => {
expect(utils.queryByText('9999')).toBeInTheDocument();
});
});

test('it should display help popover if count is 0 and hasHelpPopover=true', async () => {
const utils = renderCell({ agentCount: 0, hasHelpPopover: true });
await act(async () => {
expect(utils.queryByText('9999')).not.toBeInTheDocument();
expect(utils.queryByText('Add agent')).toBeInTheDocument();
expect(
utils.container.querySelector('[data-test-subj="addAgentHelpPopover"]')
).toBeInTheDocument();
});
});
test('it should not display help popover if count is > 0 and hasHelpPopover=true', async () => {
const utils = renderCell({ agentCount: 9999, hasHelpPopover: true });
await act(async () => {
expect(utils.queryByText('9999')).toBeInTheDocument();
expect(utils.queryByText('Add agent')).not.toBeInTheDocument();
expect(
utils.container.querySelector('[data-test-subj="addAgentHelpPopover"]')
).not.toBeInTheDocument();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,43 @@
* 2.0.
*/

import React from 'react';
import React, { useState } from 'react';

import { EuiButton } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';

import { LinkedAgentCount } from '../../../../../../components';
import { LinkedAgentCount, AddAgentHelpPopover } from '../../../../../../components';

const AddAgentButton = ({ onAddAgent }: { onAddAgent: () => void }) => (
<EuiButton iconType="plusInCircle" data-test-subj="addAgentButton" onClick={onAddAgent}>
<FormattedMessage
id="xpack.fleet.epm.packageDetails.integrationList.addAgent"
defaultMessage="Add agent"
/>
</EuiButton>
);

const AddAgentButtonWithPopover = ({ onAddAgent }: { onAddAgent: () => void }) => {
const button = <AddAgentButton onAddAgent={onAddAgent} />;
const [isHelpOpen, setIsHelpOpen] = useState<boolean>(true);
return (
<AddAgentHelpPopover
button={button}
isOpen={isHelpOpen}
closePopover={() => setIsHelpOpen(false)}
/>
);
};

export const PackagePolicyAgentsCell = ({
agentPolicyId,
agentCount = 0,
onAddAgent,
hasHelpPopover = false,
}: {
agentPolicyId: string;
agentCount?: number;
hasHelpPopover?: boolean;
onAddAgent: () => void;
}) => {
if (agentCount > 0) {
Expand All @@ -31,12 +54,9 @@ export const PackagePolicyAgentsCell = ({
);
}

return (
<EuiButton iconType="plusInCircle" data-test-subj="addAgentButton" onClick={onAddAgent}>
<FormattedMessage
id="xpack.fleet.epm.packageDetails.integrationList.addAgent"
defaultMessage="Add agent"
/>
</EuiButton>
);
if (!hasHelpPopover) {
return <AddAgentButton onAddAgent={onAddAgent} />;
}

return <AddAgentButtonWithPopover onAddAgent={onAddAgent} />;
};
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ export const PackagePoliciesPage = ({ name, version }: PackagePoliciesPanelProps
() => queryParams.get('addAgentToPolicyId'),
[queryParams]
);
const showAddAgentHelpForPolicyId = useMemo(
() => queryParams.get('showAddAgentHelpForPolicyId'),
[queryParams]
);
const [flyoutOpenForPolicyId, setFlyoutOpenForPolicyId] = useState<string | null>(
agentPolicyIdFromParams
);
Expand Down Expand Up @@ -294,6 +298,7 @@ export const PackagePoliciesPage = ({ name, version }: PackagePoliciesPanelProps
agentPolicyId={agentPolicy.id}
agentCount={agentPolicy.agents}
onAddAgent={() => setFlyoutOpenForPolicyId(agentPolicy.id)}
hasHelpPopover={showAddAgentHelpForPolicyId === agentPolicy.id}
/>
);
},
Expand Down Expand Up @@ -321,7 +326,7 @@ export const PackagePoliciesPage = ({ name, version }: PackagePoliciesPanelProps
},
},
],
[getHref, viewDataStep]
[getHref, showAddAgentHelpForPolicyId, viewDataStep]
);

const noItemsMessage = useMemo(() => {
Expand Down
Loading