Skip to content

Commit

Permalink
rework
Browse files Browse the repository at this point in the history
  • Loading branch information
smith committed Mar 17, 2020
1 parent 4dc10f8 commit 3f7cb0f
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,29 @@
* you may not use this file except in compliance with the Elastic License.
*/

import cytoscape from 'cytoscape';
import React, {
createContext,
CSSProperties,
ReactNode,
useCallback,
useEffect,
useState,
useRef,
useState
useEffect,
ReactNode,
createContext,
useCallback
} from 'react';
import cytoscape from 'cytoscape';
import { isRumAgentName } from '../../../../../../../plugins/apm/common/agent_name';
import {
animationOptions,
cytoscapeOptions,
nodeHeight
nodeHeight,
animationOptions
} from './cytoscapeOptions';

export const CytoscapeContext = createContext<cytoscape.Core | undefined>(
undefined
);

interface CytoscapeProps {
children?: (cy?: cytoscape.Core) => ReactNode | ReactNode;
children?: ReactNode;
elements: cytoscape.ElementDefinition[];
height: number;
width: number;
Expand Down Expand Up @@ -185,7 +185,7 @@ export function Cytoscape({
return (
<CytoscapeContext.Provider value={cy}>
<div ref={ref} style={divStyle}>
{typeof children === 'function' ? children(cy) : children}
{children}
</div>
</CytoscapeContext.Provider>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* 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 { act, render, wait } from '@testing-library/react';
import cytoscape from 'cytoscape';
import React, { FunctionComponent } from 'react';
import { MockApmPluginContextWrapper } from '../../../utils/testHelpers';
import { CytoscapeContext } from './Cytoscape';
import { EmptyBanner } from './EmptyBanner';

const cy = cytoscape({});

const wrapper: FunctionComponent = ({ children }) => (
<MockApmPluginContextWrapper>
<CytoscapeContext.Provider value={cy}>{children}</CytoscapeContext.Provider>
</MockApmPluginContextWrapper>
);

describe('EmptyBanner', () => {
describe('when cy is undefined', () => {
it('renders null', () => {
const noCytoscapeWrapper: FunctionComponent = ({ children }) => (
<MockApmPluginContextWrapper>
<CytoscapeContext.Provider value={undefined}>
{children}
</CytoscapeContext.Provider>
</MockApmPluginContextWrapper>
);
const component = render(<EmptyBanner />, {
wrapper: noCytoscapeWrapper
});

expect(component.container.children).toHaveLength(0);
});
});

describe('with no nodes', () => {
it('renders null', () => {
const component = render(<EmptyBanner />, {
wrapper
});

expect(component.container.children).toHaveLength(0);
});
});

describe('with one node', () => {
it('does not render null', async () => {
const component = render(<EmptyBanner />, { wrapper });

await act(async () => {
cy.add({ data: { id: 'test id' } });
await wait(() => {
expect(component.container.children.length).toBeGreaterThan(0);
});
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,70 @@
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 React, { useContext, useEffect, useState } from 'react';
import styled from 'styled-components';
import { ElasticDocsLink } from '../../shared/Links/ElasticDocsLink';
import { CytoscapeContext } from './Cytoscape';

const EmptyBannerCallOut = styled(EuiCallOut)`
const EmptyBannerContainer = styled('div')`
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}
left: calc(
${lightTheme.gutterTypes.gutterExtraLarge} +
${lightTheme.gutterTypes.gutterSmall}
);
position: absolute;
width: 95%;
z-index: 1;
`;

export function EmptyBanner() {
const cy = useContext(CytoscapeContext);
const [nodeCount, setNodeCount] = useState(0);

useEffect(() => {
const handler: cytoscape.EventHandler = event =>
setNodeCount(event.cy.nodes().length);

if (cy) {
cy.on('add remove', 'node', handler);
}

return () => {
if (cy) {
cy.removeListener('add remove', 'node', handler);
}
};
}, [cy]);

// Only show if there's a single node.
if (!cy || nodeCount !== 1) {
return null;
}

// Since we're absolutely positioned, we need to get the full width and
// subtract the space for controls and margins.
const width =
cy.width() -
parseInt(lightTheme.gutterTypes.gutterExtraLarge, 10) -
parseInt(lightTheme.gutterTypes.gutterLarge, 10);

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'
<EmptyBannerContainer style={{ width }}>
<EuiCallOut
title={i18n.translate('xpack.apm.serviceMap.emptyBanner.title', {
defaultMessage: "Looks like there's only a single service."
})}
</ElasticDocsLink>
</EmptyBannerCallOut>
>
{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>
</EuiCallOut>
</EmptyBannerContainer>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -181,15 +181,9 @@ export function ServiceMap({ serviceName }: ServiceMapProps) {
width={width}
style={cytoscapeDivStyle}
>
{cy => {
return (
<>
<Controls />
{serviceName && cy?.nodes().length === 1 && <EmptyBanner />}
<Popover focusedServiceName={serviceName} />
</>
);
}}
<Controls />
{serviceName && <EmptyBanner />}
<Popover focusedServiceName={serviceName} />
</Cytoscape>
</div>
) : (
Expand Down

0 comments on commit 3f7cb0f

Please sign in to comment.