[Uptime] fix multiple scrolls on waterfall view (#87281)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Shahzad 2021-01-06 18:17:16 +01:00 committed by GitHub
parent 14fde6d277
commit 4b4d6a6bb8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 102 additions and 11 deletions

View file

@ -44,7 +44,7 @@ export const PageHeader = () => {
const DatePickerComponent = () =>
isCertRoute ? (
<CertRefreshBtn />
) : isStepDetailRoute ? null : (
) : (
<StyledPicker grow={false} style={{ flexBasis: 485 }}>
<UptimeDatePicker />
</StyledPicker>
@ -52,6 +52,10 @@ export const PageHeader = () => {
const isMonRoute = useRouteMatch(MONITOR_ROUTE);
if (isStepDetailRoute) {
return null;
}
return (
<>
<SyntheticsCallout />

View file

@ -15,7 +15,7 @@ import {
RenderItem,
} from '../../waterfall';
const renderSidebarItem: RenderItem<SidebarItem> = (item, index) => {
export const renderSidebarItem: RenderItem<SidebarItem> = (item, index) => {
const { status } = item;
const isErrorStatusCode = (statusCode: number) => {
@ -43,7 +43,7 @@ const renderSidebarItem: RenderItem<SidebarItem> = (item, index) => {
);
};
const renderLegendItem: RenderItem<LegendItem> = (item) => {
export const renderLegendItem: RenderItem<LegendItem> = (item) => {
return <EuiHealth color={item.colour}>{item.name}</EuiHealth>;
};
@ -81,6 +81,7 @@ export const WaterfallChartWrapper: React.FC<Props> = ({ data }) => {
}}
renderSidebarItem={renderSidebarItem}
renderLegendItem={renderLegendItem}
fullHeight={true}
/>
</WaterfallProvider>
);

View file

@ -9,11 +9,11 @@ import { euiStyled } from '../../../../../../../observability/public';
import { FIXED_AXIS_HEIGHT } from './constants';
interface WaterfallChartOuterContainerProps {
height?: number;
height?: string;
}
export const WaterfallChartOuterContainer = euiStyled.div<WaterfallChartOuterContainerProps>`
height: ${(props) => (props.height ? `${props.height}px` : 'auto')};
height: ${(props) => (props.height ? `${props.height}` : 'auto')};
overflow-y: ${(props) => (props.height ? 'scroll' : 'visible')};
overflow-x: hidden;
`;

View file

@ -0,0 +1,68 @@
/*
* 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 React from 'react';
import { of } from 'rxjs';
import { MountWithReduxProvider, mountWithRouter } from '../../../../../lib';
import { KibanaContextProvider } from '../../../../../../../../../src/plugins/kibana_react/public';
import { WaterfallChart } from './waterfall_chart';
import {
renderLegendItem,
renderSidebarItem,
} from '../../step_detail/waterfall/waterfall_chart_wrapper';
import { EuiThemeProvider } from '../../../../../../../observability/public';
import { WaterfallChartOuterContainer } from './styles';
describe('waterfall', () => {
it('sets the correct height in case of full height', () => {
const core = mockCore();
const Component = () => {
return (
<WaterfallChart
tickFormat={(d: number) => `${Number(d).toFixed(0)} ms`}
domain={{
max: 3371,
min: 0,
}}
barStyleAccessor={(datum) => {
return datum.datum.config.colour;
}}
renderSidebarItem={renderSidebarItem}
renderLegendItem={renderLegendItem}
fullHeight={true}
/>
);
};
const component = mountWithRouter(
<MountWithReduxProvider>
<EuiThemeProvider darkMode={false}>
<KibanaContextProvider services={{ ...core }}>
<Component />
</KibanaContextProvider>
</EuiThemeProvider>
</MountWithReduxProvider>
);
const chartWrapper = component.find(WaterfallChartOuterContainer);
expect(chartWrapper.get(0).props.height).toBe('calc(100vh - 0px)');
});
});
const mockCore: () => any = () => {
return {
application: {
getUrlForApp: () => '/app/uptime',
navigateToUrl: jest.fn(),
},
uiSettings: {
get: (key: string) => 'MMM D, YYYY @ HH:mm:ss.SSS',
get$: (key: string) => of('MMM D, YYYY @ HH:mm:ss.SSS'),
},
};
};

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import React, { useMemo } from 'react';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import {
Axis,
@ -63,11 +63,12 @@ export interface WaterfallChartProps {
barStyleAccessor: BarStyleAccessor;
renderSidebarItem?: RenderItem;
renderLegendItem?: RenderItem;
maxHeight?: number;
maxHeight?: string;
fullHeight?: boolean;
}
const getUniqueBars = (data: WaterfallData) => {
return data.reduce<Set<number>>((acc, item) => {
return (data ?? []).reduce<Set<number>>((acc, item) => {
if (!acc.has(item.x)) {
acc.add(item.x);
return acc;
@ -86,7 +87,8 @@ export const WaterfallChart = ({
barStyleAccessor,
renderSidebarItem,
renderLegendItem,
maxHeight = 800,
maxHeight = '800px',
fullHeight = false,
}: WaterfallChartProps) => {
const { data, sidebarItems, legendItems } = useWaterfallContext();
@ -100,13 +102,24 @@ export const WaterfallChart = ({
return darkMode ? EUI_CHARTS_THEME_DARK.theme : EUI_CHARTS_THEME_LIGHT.theme;
}, [darkMode]);
const chartWrapperDivRef = useRef<HTMLDivElement | null>(null);
const [height, setHeight] = useState<string>(maxHeight);
const shouldRenderSidebar =
sidebarItems && sidebarItems.length > 0 && renderSidebarItem ? true : false;
const shouldRenderLegend =
legendItems && legendItems.length > 0 && renderLegendItem ? true : false;
useEffect(() => {
if (fullHeight && chartWrapperDivRef.current) {
const chartOffset = chartWrapperDivRef.current.getBoundingClientRect().top;
setHeight(`calc(100vh - ${chartOffset}px)`);
}
}, [chartWrapperDivRef, fullHeight]);
return (
<WaterfallChartOuterContainer height={maxHeight}>
<WaterfallChartOuterContainer height={height}>
<>
<WaterfallChartFixedTopContainer>
<EuiFlexGroup gutterSize="none" responsive={false}>
@ -153,7 +166,12 @@ export const WaterfallChart = ({
</EuiFlexItem>
</EuiFlexGroup>
</WaterfallChartFixedTopContainer>
<EuiFlexGroup gutterSize="none" responsive={false} style={{ paddingTop: '10px' }}>
<EuiFlexGroup
gutterSize="none"
responsive={false}
style={{ paddingTop: '10px' }}
ref={chartWrapperDivRef}
>
{shouldRenderSidebar && (
<Sidebar items={sidebarItems!} height={generatedHeight} render={renderSidebarItem!} />
)}