diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/LoadingOverlay.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/LoadingOverlay.tsx index 89b0171724b54..e5fe752d68841 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/LoadingOverlay.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/LoadingOverlay.tsx @@ -8,6 +8,7 @@ import theme from '@elastic/eui/dist/eui_theme_light.json'; import React from 'react'; import { EuiProgress, EuiText, EuiSpacer } from '@elastic/eui'; import styled from 'styled-components'; +import { i18n } from '@kbn/i18n'; const Container = styled.div` position: relative; @@ -29,26 +30,43 @@ const ProgressBarContainer = styled.div` max-width: 600px; `; -const Content = styled.div<{ isLoading: boolean }>` - ${props => - props.isLoading - ? ` - pointer-events: none; - opacity: 0.5; - ` - : ''} -`; +function Content({ + isInteractive, + children +}: { + isInteractive: boolean; + children: React.ReactNode; +}) { + return ( +
+ {children} +
+ ); +} interface Props { children: React.ReactNode; isLoading: boolean; percentageLoaded: number; + isInteractive: boolean; } export const LoadingOverlay = ({ children, isLoading, - percentageLoaded + percentageLoaded, + isInteractive }: Props) => ( {isLoading && ( @@ -63,10 +81,13 @@ export const LoadingOverlay = ({ - {'Loading service map... This might take a short while.'} + {i18n.translate('xpack.apm.loadingServiceMap', { + defaultMessage: + 'Loading service map... This might take a short while.' + })} )} - {children} + {children} ); diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/index.tsx index 3f0fb7a08f20a..bbbf70dc5832c 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/index.tsx @@ -112,6 +112,7 @@ export function ServiceMap({ serviceName }: ServiceMapProps) { const [responses, setResponses] = useState([]); const [isLoading, setIsLoading] = useState(true); + const [isInteractive, setIsInteractive] = useState(false); const percentageLoadedRef = useRef(0); const [percentageLoaded, setPercentageLoaded] = useState( percentageLoadedRef.current @@ -151,7 +152,7 @@ export function ServiceMap({ serviceName }: ServiceMapProps) { const shouldGetNext = responses.length + 1 < MAX_REQUESTS && data.after; if (shouldGetNext) { - percentageLoadedRef.current += 10; + percentageLoadedRef.current += 30; setPercentageLoaded(percentageLoadedRef.current); await getNext({ after: data.after }); } @@ -164,6 +165,13 @@ export function ServiceMap({ serviceName }: ServiceMapProps) { useEffect(() => { percentageLoadedRef.current = 5; setPercentageLoaded(percentageLoadedRef.current); + + // Allow user interaction after 5 seconds regardless of load status + setIsInteractive(false); + setTimeout(() => { + setIsInteractive(true); + }, 5000); + getNext({ reset: true }).then(() => { percentageLoadedRef.current = 100; setPercentageLoaded(percentageLoadedRef.current); @@ -288,33 +296,37 @@ export function ServiceMap({ serviceName }: ServiceMapProps) { ); }); + const updateMap = () => { + renderedElements.current = elements; + if (openToast.current) { + notifications.toasts.remove(openToast.current); + } + forceUpdate(); + }; + if (renderedElements.current.length === 0) { renderedElements.current = elements; } else if (newData.length && !openToast.current) { - openToast.current = notifications.toasts.add({ - title: i18n.translate('xpack.apm.newServiceMapData', { - defaultMessage: `Newly discovered connections are available.` - }), - onClose: () => { - openToast.current = null; - }, - toastLifeTimeMs: 24 * 60 * 60 * 1000, - text: toMountPoint( - { - renderedElements.current = elements; - if (openToast.current) { - notifications.toasts.remove(openToast.current); - } - forceUpdate(); - }} - > - {i18n.translate('xpack.apm.updateServiceMap', { - defaultMessage: 'Update map' - })} - - ) - }).id; + if (isInteractive) { + openToast.current = notifications.toasts.add({ + title: i18n.translate('xpack.apm.newServiceMapData', { + defaultMessage: `Newly discovered connections are available.` + }), + onClose: () => { + openToast.current = null; + }, + toastLifeTimeMs: 24 * 60 * 60 * 1000, + text: toMountPoint( + + {i18n.translate('xpack.apm.updateServiceMap', { + defaultMessage: 'Update map' + })} + + ) + }).id; + } else { + updateMap(); + } } useEffect(() => { @@ -326,7 +338,11 @@ export function ServiceMap({ serviceName }: ServiceMapProps) { }, [notifications.toasts]); return isValidPlatinumLicense ? ( - +