diff --git a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupOverview/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupOverview/index.tsx index 2e1efabf47b2c..2daf5e55d4e72 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupOverview/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupOverview/index.tsx @@ -95,39 +95,42 @@ const ErrorGroupOverview: React.FC = () => { } return ( - <EuiFlexGroup> - <EuiFlexItem grow={1}> - <LocalUIFilters {...localUIFiltersConfig} /> - </EuiFlexItem> - <EuiFlexItem grow={7}> - <EuiFlexGroup> - <EuiFlexItem> - <EuiPanel> - <ErrorDistribution - distribution={errorDistributionData} - title={i18n.translate( - 'xpack.apm.serviceDetails.metrics.errorOccurrencesChartTitle', - { - defaultMessage: 'Error occurrences' - } - )} - /> - </EuiPanel> - </EuiFlexItem> - </EuiFlexGroup> + <> + <EuiSpacer /> + <EuiFlexGroup> + <EuiFlexItem grow={1}> + <LocalUIFilters {...localUIFiltersConfig} /> + </EuiFlexItem> + <EuiFlexItem grow={7}> + <EuiFlexGroup> + <EuiFlexItem> + <EuiPanel> + <ErrorDistribution + distribution={errorDistributionData} + title={i18n.translate( + 'xpack.apm.serviceDetails.metrics.errorOccurrencesChartTitle', + { + defaultMessage: 'Error occurrences' + } + )} + /> + </EuiPanel> + </EuiFlexItem> + </EuiFlexGroup> - <EuiSpacer size="s" /> - - <EuiPanel> - <EuiTitle size="xs"> - <h3>Errors</h3> - </EuiTitle> <EuiSpacer size="s" /> - <ErrorGroupList items={errorGroupListData} /> - </EuiPanel> - </EuiFlexItem> - </EuiFlexGroup> + <EuiPanel> + <EuiTitle size="xs"> + <h3>Errors</h3> + </EuiTitle> + <EuiSpacer size="s" /> + + <ErrorGroupList items={errorGroupListData} /> + </EuiPanel> + </EuiFlexItem> + </EuiFlexGroup> + </> ); }; diff --git a/x-pack/legacy/plugins/apm/public/components/app/Home/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/Home/index.tsx index 4c98618d7de8a..5f8fa8bf5dc07 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/Home/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/Home/index.tsx @@ -5,27 +5,26 @@ */ import { + EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, - EuiTitle, - EuiButtonEmpty, EuiTabs, - EuiSpacer + EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; import { $ElementType } from 'utility-types'; +import { useApmPluginContext } from '../../../hooks/useApmPluginContext'; import { ApmHeader } from '../../shared/ApmHeader'; -import { SetupInstructionsLink } from '../../shared/Links/SetupInstructionsLink'; -import { ServiceOverview } from '../ServiceOverview'; -import { TraceOverview } from '../TraceOverview'; -import { ServiceOverviewLink } from '../../shared/Links/apm/ServiceOverviewLink'; -import { TraceOverviewLink } from '../../shared/Links/apm/TraceOverviewLink'; import { EuiTabLink } from '../../shared/EuiTabLink'; -import { SettingsLink } from '../../shared/Links/apm/SettingsLink'; import { ServiceMapLink } from '../../shared/Links/apm/ServiceMapLink'; +import { ServiceOverviewLink } from '../../shared/Links/apm/ServiceOverviewLink'; +import { SettingsLink } from '../../shared/Links/apm/SettingsLink'; +import { TraceOverviewLink } from '../../shared/Links/apm/TraceOverviewLink'; +import { SetupInstructionsLink } from '../../shared/Links/SetupInstructionsLink'; import { ServiceMap } from '../ServiceMap'; -import { useApmPluginContext } from '../../../hooks/useApmPluginContext'; +import { ServiceOverview } from '../ServiceOverview'; +import { TraceOverview } from '../TraceOverview'; function getHomeTabs({ serviceMapEnabled = false @@ -116,7 +115,6 @@ export function Home({ tab }: Props) { </EuiTabLink> ))} </EuiTabs> - <EuiSpacer /> {selectedTab.render()} </div> ); diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx index 75ea02491967e..7ab2f7bac8ae2 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx @@ -4,24 +4,24 @@ * you may not use this file except in compliance with the Elastic License. */ +import { EuiTabs } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; -import { EuiTabs, EuiSpacer } from '@elastic/eui'; -import { ErrorGroupOverview } from '../ErrorGroupOverview'; -import { TransactionOverview } from '../TransactionOverview'; -import { ServiceMetrics } from '../ServiceMetrics'; -import { isRumAgentName, isJavaAgentName } from '../../../../common/agent_name'; -import { EuiTabLink } from '../../shared/EuiTabLink'; +import { isJavaAgentName, isRumAgentName } from '../../../../common/agent_name'; +import { useAgentName } from '../../../hooks/useAgentName'; +import { useApmPluginContext } from '../../../hooks/useApmPluginContext'; import { useUrlParams } from '../../../hooks/useUrlParams'; -import { TransactionOverviewLink } from '../../shared/Links/apm/TransactionOverviewLink'; +import { EuiTabLink } from '../../shared/EuiTabLink'; import { ErrorOverviewLink } from '../../shared/Links/apm/ErrorOverviewLink'; import { MetricOverviewLink } from '../../shared/Links/apm/MetricOverviewLink'; +import { ServiceMapLink } from '../../shared/Links/apm/ServiceMapLink'; import { ServiceNodeOverviewLink } from '../../shared/Links/apm/ServiceNodeOverviewLink'; -import { ServiceNodeOverview } from '../ServiceNodeOverview'; -import { useAgentName } from '../../../hooks/useAgentName'; +import { TransactionOverviewLink } from '../../shared/Links/apm/TransactionOverviewLink'; +import { ErrorGroupOverview } from '../ErrorGroupOverview'; import { ServiceMap } from '../ServiceMap'; -import { ServiceMapLink } from '../../shared/Links/apm/ServiceMapLink'; -import { useApmPluginContext } from '../../../hooks/useApmPluginContext'; +import { ServiceMetrics } from '../ServiceMetrics'; +import { ServiceNodeOverview } from '../ServiceNodeOverview'; +import { TransactionOverview } from '../TransactionOverview'; interface Props { tab: 'transactions' | 'errors' | 'metrics' | 'nodes' | 'service-map'; @@ -124,7 +124,6 @@ export function ServiceDetailTabs({ tab }: Props) { </EuiTabLink> ))} </EuiTabs> - <EuiSpacer /> {selectedTab ? selectedTab.render() : null} </> ); diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Cytoscape.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Cytoscape.tsx index d69fa5d895b9e..f7d74bee1aa50 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Cytoscape.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Cytoscape.tsx @@ -25,6 +25,7 @@ export const CytoscapeContext = createContext<cytoscape.Core | undefined>( interface CytoscapeProps { children?: ReactNode; elements: cytoscape.ElementDefinition[]; + height: number; serviceName?: string; style?: CSSProperties; } @@ -54,11 +55,16 @@ function useCytoscape(options: cytoscape.CytoscapeOptions) { export function Cytoscape({ children, elements, + height, serviceName, style }: CytoscapeProps) { const [ref, cy] = useCytoscape({ ...cytoscapeOptions, elements }); + // Add the height to the div style. The height is a separate prop because it + // is required and can trigger rendering when changed. + const divStyle = { ...style, height }; + // Trigger a custom "data" event when data changes useEffect(() => { if (cy) { @@ -108,7 +114,7 @@ export function Cytoscape({ return ( <CytoscapeContext.Provider value={cy}> - <div ref={ref} style={style}> + <div ref={ref} style={divStyle}> {children} </div> </CytoscapeContext.Provider> 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 efafdbcecd41c..c08d3acbf1861 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 @@ -31,16 +31,11 @@ const ProgressBarContainer = styled.div` `; interface Props { - children: React.ReactNode; isLoading: boolean; percentageLoaded: number; } -export const LoadingOverlay = ({ - children, - isLoading, - percentageLoaded -}: Props) => ( +export const LoadingOverlay = ({ isLoading, percentageLoaded }: Props) => ( <Container> {isLoading && ( <Overlay> @@ -61,6 +56,5 @@ export const LoadingOverlay = ({ </EuiText> </Overlay> )} - {children} </Container> ); 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 a8e6f964f4d0c..24fb0b9e5d8a3 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 @@ -30,13 +30,13 @@ import { getCytoscapeElements } from './get_cytoscape_elements'; import { LoadingOverlay } from './LoadingOverlay'; import { PlatinumLicensePrompt } from './PlatinumLicensePrompt'; import { Popover } from './Popover'; +import { useRefHeight } from './useRefHeight'; interface ServiceMapProps { serviceName?: string; } const cytoscapeDivStyle = { - height: '85vh', background: `linear-gradient( 90deg, ${theme.euiPageBackgroundColor} @@ -52,7 +52,8 @@ linear-gradient( center, ${theme.euiColorLightShade}`, backgroundSize: `${theme.euiSizeL} ${theme.euiSizeL}`, - margin: `-${theme.gutterTypes.gutterLarge}` + margin: `-${theme.gutterTypes.gutterLarge}`, + marginTop: 0 }; const MAX_REQUESTS = 5; @@ -198,17 +199,27 @@ export function ServiceMap({ serviceName }: ServiceMapProps) { license?.isActive && (license?.type === 'platinum' || license?.type === 'trial'); + const [wrapperRef, height] = useRefHeight(); + return isValidPlatinumLicense ? ( - <LoadingOverlay isLoading={isLoading} percentageLoaded={percentageLoaded}> + <div + style={{ height: height - parseInt(theme.gutterTypes.gutterLarge, 10) }} + ref={wrapperRef} + > <Cytoscape elements={renderedElements.current} serviceName={serviceName} + height={height} style={cytoscapeDivStyle} > + <LoadingOverlay + isLoading={isLoading} + percentageLoaded={percentageLoaded} + /> <Controls /> <Popover focusedServiceName={serviceName} /> </Cytoscape> - </LoadingOverlay> + </div> ) : ( <PlatinumLicensePrompt /> ); diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/useRefHeight.ts b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/useRefHeight.ts new file mode 100644 index 0000000000000..b8fba47acd2d6 --- /dev/null +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/useRefHeight.ts @@ -0,0 +1,20 @@ +/* + * 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 { MutableRefObject, useRef } from 'react'; +import { useWindowSize } from 'react-use'; + +export function useRefHeight(): [ + MutableRefObject<HTMLDivElement | null>, + number +] { + const ref = useRef<HTMLDivElement>(null); + const windowHeight = useWindowSize().height; + const topOffset = ref.current?.getBoundingClientRect()?.top ?? 0; + + const height = ref.current ? windowHeight - topOffset : 0; + + return [ref, height]; +} diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMetrics/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMetrics/index.tsx index d01093be801a2..0fb8c00a2b162 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMetrics/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMetrics/index.tsx @@ -43,24 +43,27 @@ export function ServiceMetrics({ agentName }: ServiceMetricsProps) { ); return ( - <EuiFlexGroup> - <EuiFlexItem grow={1}> - <LocalUIFilters {...localFiltersConfig} /> - </EuiFlexItem> - <EuiFlexItem grow={7}> - <ChartsSyncContextProvider> - <EuiFlexGrid columns={2} gutterSize="s"> - {data.charts.map(chart => ( - <EuiFlexItem key={chart.key}> - <EuiPanel> - <MetricsChart start={start} end={end} chart={chart} /> - </EuiPanel> - </EuiFlexItem> - ))} - </EuiFlexGrid> - <EuiSpacer size="xxl" /> - </ChartsSyncContextProvider> - </EuiFlexItem> - </EuiFlexGroup> + <> + <EuiSpacer /> + <EuiFlexGroup> + <EuiFlexItem grow={1}> + <LocalUIFilters {...localFiltersConfig} /> + </EuiFlexItem> + <EuiFlexItem grow={7}> + <ChartsSyncContextProvider> + <EuiFlexGrid columns={2} gutterSize="s"> + {data.charts.map(chart => ( + <EuiFlexItem key={chart.key}> + <EuiPanel> + <MetricsChart start={start} end={end} chart={chart} /> + </EuiPanel> + </EuiFlexItem> + ))} + </EuiFlexGrid> + <EuiSpacer size="xxl" /> + </ChartsSyncContextProvider> + </EuiFlexItem> + </EuiFlexGroup> + </> ); } diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx index a118871a5e268..4e57cb47691be 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx @@ -4,7 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ import React, { useMemo } from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiToolTip } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiPanel, + EuiToolTip, + EuiSpacer +} from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import styled from 'styled-components'; import { UNIDENTIFIED_SERVICE_NODES_LABEL } from '../../../../common/i18n'; @@ -150,25 +156,31 @@ const ServiceNodeOverview = () => { ]; return ( - <EuiFlexGroup> - <EuiFlexItem grow={1}> - <LocalUIFilters {...localFiltersConfig} /> - </EuiFlexItem> - <EuiFlexItem grow={7}> - <EuiPanel> - <ManagedTable - noItemsMessage={i18n.translate('xpack.apm.jvmsTable.noJvmsLabel', { - defaultMessage: 'No JVMs were found' - })} - items={items} - columns={columns} - initialPageSize={INITIAL_PAGE_SIZE} - initialSortField={INITIAL_SORT_FIELD} - initialSortDirection={INITIAL_SORT_DIRECTION} - /> - </EuiPanel> - </EuiFlexItem> - </EuiFlexGroup> + <> + <EuiSpacer /> + <EuiFlexGroup> + <EuiFlexItem grow={1}> + <LocalUIFilters {...localFiltersConfig} /> + </EuiFlexItem> + <EuiFlexItem grow={7}> + <EuiPanel> + <ManagedTable + noItemsMessage={i18n.translate( + 'xpack.apm.jvmsTable.noJvmsLabel', + { + defaultMessage: 'No JVMs were found' + } + )} + items={items} + columns={columns} + initialPageSize={INITIAL_PAGE_SIZE} + initialSortField={INITIAL_SORT_FIELD} + initialSortDirection={INITIAL_SORT_DIRECTION} + /> + </EuiPanel> + </EuiFlexItem> + </EuiFlexGroup> + </> ); }; diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceOverview/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceOverview/index.tsx index 05ccc691ecdba..b522736c80f9b 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceOverview/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceOverview/index.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiPanel, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiPanel, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import { EuiLink } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { useEffect, useMemo } from 'react'; @@ -94,23 +94,26 @@ export function ServiceOverview() { ); return ( - <EuiFlexGroup> - <EuiFlexItem grow={1}> - <LocalUIFilters {...localFiltersConfig} /> - </EuiFlexItem> - <EuiFlexItem grow={7}> - <EuiPanel> - <ServiceList - items={data.items} - noItemsMessage={ - <NoServicesMessage - historicalDataFound={data.hasHistoricalData} - status={status} - /> - } - /> - </EuiPanel> - </EuiFlexItem> - </EuiFlexGroup> + <> + <EuiSpacer /> + <EuiFlexGroup> + <EuiFlexItem grow={1}> + <LocalUIFilters {...localFiltersConfig} /> + </EuiFlexItem> + <EuiFlexItem grow={7}> + <EuiPanel> + <ServiceList + items={data.items} + noItemsMessage={ + <NoServicesMessage + historicalDataFound={data.hasHistoricalData} + status={status} + /> + } + /> + </EuiPanel> + </EuiFlexItem> + </EuiFlexGroup> + </> ); } diff --git a/x-pack/legacy/plugins/apm/public/components/app/TraceOverview/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/TraceOverview/index.tsx index cf701d02aa5cb..dd3e2d13826dc 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/TraceOverview/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/TraceOverview/index.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiPanel, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiPanel, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import React, { useMemo } from 'react'; import { FETCH_STATUS, useFetcher } from '../../../hooks/useFetcher'; import { TraceList } from './TraceList'; @@ -47,15 +47,21 @@ export function TraceOverview() { }, []); return ( - <EuiFlexGroup> - <EuiFlexItem grow={1}> - <LocalUIFilters {...localUIFiltersConfig} showCount={false} /> - </EuiFlexItem> - <EuiFlexItem grow={7}> - <EuiPanel> - <TraceList items={data} isLoading={status === FETCH_STATUS.LOADING} /> - </EuiPanel> - </EuiFlexItem> - </EuiFlexGroup> + <> + <EuiSpacer /> + <EuiFlexGroup> + <EuiFlexItem grow={1}> + <LocalUIFilters {...localUIFiltersConfig} showCount={false} /> + </EuiFlexItem> + <EuiFlexItem grow={7}> + <EuiPanel> + <TraceList + items={data} + isLoading={status === FETCH_STATUS.LOADING} + /> + </EuiPanel> + </EuiFlexItem> + </EuiFlexGroup> + </> ); } diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionOverview/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/TransactionOverview/index.tsx index 439e3d80eef4f..2cf01f8b40a09 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/TransactionOverview/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/TransactionOverview/index.tsx @@ -119,41 +119,44 @@ export function TransactionOverview() { } return ( - <EuiFlexGroup> - <EuiFlexItem grow={1}> - <LocalUIFilters {...localFiltersConfig}> - <TransactionTypeFilter transactionTypes={serviceTransactionTypes} /> - <EuiSpacer size="xl" /> - <EuiHorizontalRule margin="none" /> - </LocalUIFilters> - </EuiFlexItem> - <EuiFlexItem grow={7}> - <ChartsSyncContextProvider> - <TransactionBreakdown initialIsOpen={true} /> + <> + <EuiSpacer /> + <EuiFlexGroup> + <EuiFlexItem grow={1}> + <LocalUIFilters {...localFiltersConfig}> + <TransactionTypeFilter transactionTypes={serviceTransactionTypes} /> + <EuiSpacer size="xl" /> + <EuiHorizontalRule margin="none" /> + </LocalUIFilters> + </EuiFlexItem> + <EuiFlexItem grow={7}> + <ChartsSyncContextProvider> + <TransactionBreakdown initialIsOpen={true} /> + + <EuiSpacer size="s" /> + + <TransactionCharts + hasMLJob={hasMLJob} + charts={transactionCharts} + location={location} + urlParams={urlParams} + /> + </ChartsSyncContextProvider> <EuiSpacer size="s" /> - <TransactionCharts - hasMLJob={hasMLJob} - charts={transactionCharts} - location={location} - urlParams={urlParams} - /> - </ChartsSyncContextProvider> - - <EuiSpacer size="s" /> - - <EuiPanel> - <EuiTitle size="xs"> - <h3>Transactions</h3> - </EuiTitle> - <EuiSpacer size="s" /> - <TransactionList - isLoading={transactionListStatus === 'loading'} - items={transactionListData} - /> - </EuiPanel> - </EuiFlexItem> - </EuiFlexGroup> + <EuiPanel> + <EuiTitle size="xs"> + <h3>Transactions</h3> + </EuiTitle> + <EuiSpacer size="s" /> + <TransactionList + isLoading={transactionListStatus === 'loading'} + items={transactionListData} + /> + </EuiPanel> + </EuiFlexItem> + </EuiFlexGroup> + </> ); } diff --git a/x-pack/legacy/plugins/apm/public/new-platform/plugin.tsx b/x-pack/legacy/plugins/apm/public/new-platform/plugin.tsx index e6c81d1190ce3..26e0f25cbb666 100644 --- a/x-pack/legacy/plugins/apm/public/new-platform/plugin.tsx +++ b/x-pack/legacy/plugins/apm/public/new-platform/plugin.tsx @@ -39,7 +39,7 @@ import { setReadonlyBadge } from './updateBadge'; export const REACT_APP_ROOT_ID = 'react-apm-root'; -const MainContainer = styled.main` +const MainContainer = styled.div` min-width: ${px(unit * 50)}; padding: ${px(units.plus)}; height: 100%; @@ -47,7 +47,7 @@ const MainContainer = styled.main` const App = () => { return ( - <MainContainer data-test-subj="apmMainContainer"> + <MainContainer data-test-subj="apmMainContainer" role="main"> <UpdateBreadcrumbs routes={routes} /> <Route component={ScrollToTopOnPathChange} /> <Switch>