import { EuiFlexGroup , EuiFlexItem , EuiLoadingSpinner } from '@elastic/eui' ; import { i18n } from '@kbn/i18n' ; import React , { ReactChild , useState } from 'react' ; import { useTheme } from '../../../hooks/use_theme' ; import { ContainerType } from '../../../../common/service_metadata' ; import { FETCH_STATUS , useFetcher } from '../../../hooks/use_fetcher' ; import { getAgentIcon } from '../agent_icon/get_agent_icon' ; import { CloudDetails } from './cloud_details' ; import { ContainerDetails } from './container_details' ; import { IconPopover } from './icon_popover' ; import { ServiceDetails } from './service_details' ; interface Props { serviceName : string ; start : string ; end : string ; } const cloudIcons = { gcp : 'logoGCP' , aws : 'logoAWS' , azure : 'logoAzure' , } ; export function getCloudIcon ( provider ? ) { if ( provider ) { return cloudIcons [ provider ] ; } } export function getContainerIcon ( container ? ) { if ( ! container ) { return ; } switch ( container ) { case 'Kubernetes' : return 'logoKubernetes' ; default : return 'logoDocker' ; } } type Icons = 'service' | 'container' | 'cloud' | 'alerts' ; export interface PopoverItem { key : Icons ; icon : { type ? : string ; size ? : 's' | 'm' | 'l' ; } ; isVisible : boolean ; title : string ; component : ReactChild ; } export function ServiceIcons ( { start , end , serviceName } ) { const [ selectedIconPopover , setSelectedIconPopover ] = useState < Icons | null > ( ) ; const theme = useTheme ( ) ; const { data : icons , status : iconsFetchStatus } = useFetcher ( ( callApmApi ) => { if ( serviceName && start && end ) { return callApmApi ( { endpoint : 'GET /internal/apm/services/{serviceName}/metadata/icons' , params : { path : { serviceName } , query : { start , end } , } , } ) ; } } , [ serviceName , start , end ] ) ; const { data : details , status : detailsFetchStatus } = useFetcher ( ( callApmApi ) => { if ( selectedIconPopover && serviceName && start && end ) { return callApmApi ( { isCachable : true , endpoint : 'GET /internal/apm/services/{serviceName}/metadata/details' , params : { path : { serviceName } , query : { start , end } , } , } ) ; } } , [ selectedIconPopover , serviceName , start , end ] ) ; const isLoading = ! icons && iconsFetchStatus === FETCH_STATUS . LOADING ; if ( isLoading ) { return < EuiLoadingSpinner data - test - subj = "loading" / > ; } const popoverItems = [ { key : 'service' , icon : { type : getAgentIcon ( icons ?. agentName , theme . darkMode ) || 'node' , } , isVisible : ! ! icons ?. agentName , title : i18n . translate ( 'xpack.apm.serviceIcons.service' , { defaultMessage : 'Service' , } ) , component : < ServiceDetails service = { details ?. service } / > , } , { key : 'container' , icon : { type : getContainerIcon ( icons ?. containerType ) , } , isVisible : ! ! icons ?. containerType , title : i18n . translate ( 'xpack.apm.serviceIcons.container' , { defaultMessage : 'Container' , } ) , component : < ContainerDetails container = { details ?. container } />, } , { key : 'cloud' , icon : { type : getCloudIcon ( icons ?. cloudProvider ) , } , isVisible : ! ! icons ?. cloudProvider , title : i18n . translate ( 'xpack.apm.serviceIcons.cloud' , { defaultMessage : 'Cloud' , } ) , component : < CloudDetails cloud = { details ?. cloud } />, } , ] ; return ( < EuiFlexGroup gutterSize = "s" responsive = { false } > { popoverItems . map ( ( item ) => { if ( item . isVisible ) { return ( < EuiFlexItem grow = { false } data - test - subj = { item . key } key = { item . key } > < IconPopover isOpen = { selectedIconPopover === item . key } icon = { item . icon } detailsFetchStatus = { detailsFetchStatus } title = { item . title } onClick = { ( ) => { setSelectedIconPopover ( ( prevSelectedIconPopover ) => item . key === prevSelectedIconPopover ? null : item . key ) ; } } onClose = { ( ) => { setSelectedIconPopover ( null ) ; } } > { item . component } < /IconPopover> < /EuiFlexItem>); } } ) } < /EuiFlexGroup>); }