diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/host_details.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/host_details.tsx index a3862d4454c1d..b191bfe4effea 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/host_details.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/host_details.tsx @@ -12,12 +12,14 @@ import { EuiLink, EuiListGroup, EuiListGroupItem, + EuiIcon, + EuiText, } from '@elastic/eui'; import React, { memo, useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { HostMetadata } from '../../../../../../common/endpoint/types'; -import { useHostSelector, useHostLogsUrl } from '../hooks'; +import { useHostSelector, useHostLogsUrl, useHostIngestUrl } from '../hooks'; import { policyResponseStatus, uiQueryParams } from '../../store/selectors'; import { POLICY_STATUS_TO_HEALTH_COLOR } from '../host_constants'; import { FormattedDateAndTime } from '../../../../../common/components/endpoint/formatted_date_time'; @@ -32,8 +34,19 @@ const HostIds = styled(EuiListGroupItem)` } `; +const LinkToExternalApp = styled.div` + margin-top: ${(props) => props.theme.eui.ruleMargins.marginMedium}; + .linkToAppIcon { + margin-right: ${(props) => props.theme.eui.ruleMargins.marginXSmall}; + } + .linkToAppPopoutIcon { + margin-left: ${(props) => props.theme.eui.ruleMargins.marginXSmall}; + } +`; + export const HostDetails = memo(({ details }: { details: HostMetadata }) => { - const { appId, appPath, url } = useHostLogsUrl(details.host.id); + const { url: logsUrl, appId: logsAppId, appPath: logsAppPath } = useHostLogsUrl(details.host.id); + const { url: ingestUrl, appId: ingestAppId, appPath: ingestAppPath } = useHostIngestUrl(); const queryParams = useHostSelector(uiQueryParams); const policyStatus = useHostSelector( policyResponseStatus @@ -80,7 +93,7 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => { const policyStatusClickHandler = useNavigateByRouterEventHandler(policyResponseRoutePath); - const detailsResultsLower = useMemo(() => { + const detailsResultsPolicy = useMemo(() => { return [ { title: i18n.translate('xpack.securitySolution.endpoint.host.details.policy', { @@ -103,15 +116,21 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => { href={policyResponseUri} onClick={policyStatusClickHandler} > - + + + ), }, + ]; + }, [details, policyResponseUri, policyStatus, policyStatusClickHandler]); + const detailsResultsLower = useMemo(() => { + return [ { title: i18n.translate('xpack.securitySolution.endpoint.host.details.ipAddress', { defaultMessage: 'IP Address', @@ -137,15 +156,8 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => { description: details.agent.version, }, ]; - }, [ - details.agent.version, - details.endpoint.policy.applied.id, - details.host.hostname, - details.host.ip, - policyStatus, - policyResponseUri, - policyStatusClickHandler, - ]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [details.agent.version, details.host.hostname, details.host.ip]); return ( <> @@ -154,26 +166,49 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => { listItems={detailsResultsUpper} data-test-subj="hostDetailsUpperList" /> - + + + + + + + + + + - -

+ + + + -

+ ); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/hooks.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/hooks.ts index ddba6d7344ce5..51aaea20df843 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/hooks.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/hooks.ts @@ -6,14 +6,13 @@ import { useSelector } from 'react-redux'; import { useMemo } from 'react'; +import { useKibana } from '../../../../common/lib/kibana'; import { HostState } from '../types'; import { MANAGEMENT_STORE_ENDPOINTS_NAMESPACE, MANAGEMENT_STORE_GLOBAL_NAMESPACE, } from '../../../common/constants'; -import { useKibana } from '../../../../common/lib/kibana'; import { State } from '../../../../common/store'; - export function useHostSelector(selector: (state: HostState) => TSelected) { return useSelector(function (state: State) { return selector( @@ -37,3 +36,18 @@ export const useHostLogsUrl = (hostId: string): { url: string; appId: string; ap }; }, [hostId, services.application]); }; + +/** + * Returns an object that contains Ingest app and URL information + */ +export const useHostIngestUrl = (): { url: string; appId: string; appPath: string } => { + const { services } = useKibana(); + return useMemo(() => { + const appPath = `#/fleet`; + return { + url: `${services.application.getUrlForApp('ingestManager')}${appPath}`, + appId: 'ingestManager', + appPath, + }; + }, [services.application]); +}; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/configure_datasource.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/configure_datasource.tsx index db5196bfc4eb4..e80856f35081b 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/configure_datasource.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/configure_datasource.tsx @@ -37,9 +37,9 @@ export const ConfigureEndpointDatasource = memo {from === 'edit' ? (