[Uptime] fix multiple scrolls on waterfall view (#87281)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
14fde6d277
commit
4b4d6a6bb8
|
@ -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 />
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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;
|
||||
`;
|
||||
|
|
|
@ -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'),
|
||||
},
|
||||
};
|
||||
};
|
|
@ -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!} />
|
||||
)}
|
||||
|
|
Loading…
Reference in a new issue