Empty message for APM service map (#59518)
When only one node is displayed, show an empty message. Also: * Start adding a basic Jest test for the ServiceMap component * Fix bug where EuiDocsLink was rendering "children" instead of the actual children Closes #59326. Closes #59128.
This commit is contained in:
parent
3c4cf56008
commit
0d3dd97691
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { EuiCallOut } from '@elastic/eui';
|
||||
import lightTheme from '@elastic/eui/dist/eui_theme_light.json';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { ElasticDocsLink } from '../../shared/Links/ElasticDocsLink';
|
||||
|
||||
const EmptyBannerCallOut = styled(EuiCallOut)`
|
||||
margin: ${lightTheme.gutterTypes.gutterSmall};
|
||||
/* Add some extra margin so it displays to the right of the controls. */
|
||||
margin-left: calc(
|
||||
${lightTheme.gutterTypes.gutterLarge} +
|
||||
${lightTheme.gutterTypes.gutterExtraLarge}
|
||||
);
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
`;
|
||||
|
||||
export function EmptyBanner() {
|
||||
return (
|
||||
<EmptyBannerCallOut
|
||||
title={i18n.translate('xpack.apm.serviceMap.emptyBanner.title', {
|
||||
defaultMessage: "Looks like there's only a single service."
|
||||
})}
|
||||
>
|
||||
{i18n.translate('xpack.apm.serviceMap.emptyBanner.message', {
|
||||
defaultMessage:
|
||||
"We will map out connected services and external requests if we can detect them. Please make sure you're running the latest version of the APM agent."
|
||||
})}{' '}
|
||||
<ElasticDocsLink section="/apm/get-started" path="/agents.html">
|
||||
{i18n.translate('xpack.apm.serviceMap.emptyBanner.docsLink', {
|
||||
defaultMessage: 'Learn more in the docs'
|
||||
})}
|
||||
</ElasticDocsLink>
|
||||
</EmptyBannerCallOut>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { render } from '@testing-library/react';
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { License } from '../../../../../../../plugins/licensing/common/license';
|
||||
import { LicenseContext } from '../../../context/LicenseContext';
|
||||
import { MockApmPluginContextWrapper } from '../../../utils/testHelpers';
|
||||
import { ServiceMap } from './';
|
||||
|
||||
const expiredLicense = new License({
|
||||
signature: 'test signature',
|
||||
license: {
|
||||
expiryDateInMillis: 0,
|
||||
mode: 'platinum',
|
||||
status: 'expired',
|
||||
type: 'platinum',
|
||||
uid: '1'
|
||||
}
|
||||
});
|
||||
|
||||
const Wrapper: FunctionComponent = ({ children }) => {
|
||||
return (
|
||||
<LicenseContext.Provider value={expiredLicense}>
|
||||
<MockApmPluginContextWrapper>{children}</MockApmPluginContextWrapper>
|
||||
</LicenseContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
describe('ServiceMap', () => {
|
||||
describe('with an inactive license', () => {
|
||||
it('renders the license banner', async () => {
|
||||
expect(
|
||||
(
|
||||
await render(<ServiceMap />, {
|
||||
wrapper: Wrapper
|
||||
}).findAllByText(/Platinum/)
|
||||
).length
|
||||
).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -26,13 +26,14 @@ import { useLicense } from '../../../hooks/useLicense';
|
|||
import { useLoadingIndicator } from '../../../hooks/useLoadingIndicator';
|
||||
import { useLocation } from '../../../hooks/useLocation';
|
||||
import { useUrlParams } from '../../../hooks/useUrlParams';
|
||||
import { callApmApi } from '../../../services/rest/createCallApmApi';
|
||||
import { Controls } from './Controls';
|
||||
import { Cytoscape } from './Cytoscape';
|
||||
import { EmptyBanner } from './EmptyBanner';
|
||||
import { getCytoscapeElements } from './get_cytoscape_elements';
|
||||
import { PlatinumLicensePrompt } from './PlatinumLicensePrompt';
|
||||
import { Popover } from './Popover';
|
||||
import { useRefDimensions } from './useRefDimensions';
|
||||
import { callApmApi } from '../../../services/rest/createCallApmApi';
|
||||
|
||||
interface ServiceMapProps {
|
||||
serviceName?: string;
|
||||
|
@ -214,6 +215,9 @@ export function ServiceMap({ serviceName }: ServiceMapProps) {
|
|||
style={cytoscapeDivStyle}
|
||||
>
|
||||
<Controls />
|
||||
{serviceName && renderedElements.current.length === 1 && (
|
||||
<EmptyBanner />
|
||||
)}
|
||||
<Popover focusedServiceName={serviceName} />
|
||||
</Cytoscape>
|
||||
</div>
|
||||
|
|
|
@ -23,7 +23,7 @@ export function ElasticDocsLink({ section, path, children, ...rest }: Props) {
|
|||
children(href)
|
||||
) : (
|
||||
<EuiLink href={href} {...rest}>
|
||||
children
|
||||
{children}
|
||||
</EuiLink>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue