Skip to content

Commit

Permalink
[APM] Trace waterfall is visually broken (#117589) (#118016)
Browse files Browse the repository at this point in the history
* fixing accordion

* fixing trace waterfall

* removing import

* fixing test

* addressing pr changes

Co-authored-by: Kibana Machine <[email protected]>

Co-authored-by: Cauê Marcondes <[email protected]>
  • Loading branch information
kibanamachine and cauemarcondes authored Nov 9, 2021
1 parent 9e4734c commit 0751c78
Showing 1 changed file with 89 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,22 @@
* 2.0.
*/

import { EuiAccordion, EuiAccordionProps } from '@elastic/eui';
import { isEmpty } from 'lodash';
import {
EuiAccordion,
EuiAccordionProps,
EuiFlexGroup,
EuiFlexItem,
EuiIcon,
EuiText,
} from '@elastic/eui';
import React, { Dispatch, SetStateAction, useState } from 'react';
import { euiStyled } from '../../../../../../../../../../src/plugins/kibana_react/common';
import { Margins } from '../../../../../shared/charts/Timeline';
import { WaterfallItem } from './waterfall_item';
import {
IWaterfall,
IWaterfallSpanOrTransaction,
} from './waterfall_helpers/waterfall_helpers';
import { WaterfallItem } from './waterfall_item';

interface AccordionWaterfallProps {
isOpen: boolean;
Expand All @@ -28,6 +34,8 @@ interface AccordionWaterfallProps {
onClickWaterfallItem: (item: IWaterfallSpanOrTransaction) => void;
}

const ACCORDION_HEIGHT = '48px';

const StyledAccordion = euiStyled(EuiAccordion).withConfig({
shouldForwardProp: (prop) =>
!['childrenCount', 'marginLeftLevel', 'hasError'].includes(prop),
Expand All @@ -38,54 +46,33 @@ const StyledAccordion = euiStyled(EuiAccordion).withConfig({
hasError: boolean;
}
>`
.euiAccordion {
.waterfall_accordion {
border-top: 1px solid ${({ theme }) => theme.eui.euiColorLightShade};
}
.euiIEFlexWrapFix {
width: 100%;
height: 48px;
}
.euiAccordion__childWrapper {
transition: none;
}
.euiAccordion__padding--l {
padding-top: 0;
padding-bottom: 0;
}
.euiAccordion__iconWrapper {
display: flex;
position: relative;
&:after {
content: ${(props) => `'${props.childrenCount}'`};
position: absolute;
left: 20px;
top: -1px;
z-index: 1;
font-size: ${({ theme }) => theme.eui.euiFontSizeXS};
}
}
${(props) => {
const borderLeft = props.hasError
? `2px solid ${props.theme.eui.euiColorDanger};`
: `1px solid ${props.theme.eui.euiColorLightShade};`;
return `.button_${props.id} {
width: 100%;
height: ${ACCORDION_HEIGHT};
margin-left: ${props.marginLeftLevel}px;
border-left: ${borderLeft}
&:hover {
background-color: ${props.theme.eui.euiColorLightestShade};
}
}`;
//
}}
`;
const WaterfallItemContainer = euiStyled.div`
position: absolute;
width: 100%;
left: 0;
.accordion__buttonContent {
width: 100%;
height: 100%;
}
`;

export function AccordionWaterfall(props: AccordionWaterfallProps) {
Expand All @@ -111,36 +98,51 @@ export function AccordionWaterfall(props: AccordionWaterfallProps) {
// To indent the items creating the parent/child tree
const marginLeftLevel = 8 * level;

function toggleAccordion() {
setIsOpen((isCurrentOpen) => !isCurrentOpen);
}

return (
<StyledAccordion
className="waterfall_accordion"
style={{ position: 'relative' }}
buttonClassName={`button_${item.id}`}
key={item.id}
id={item.id}
hasError={item.doc.event?.outcome === 'failure'}
marginLeftLevel={marginLeftLevel}
childrenCount={children.length}
buttonContentClassName="accordion__buttonContent"
buttonContent={
<WaterfallItemContainer>
<WaterfallItem
key={item.id}
timelineMargins={timelineMargins}
color={item.color}
item={item}
totalDuration={duration}
isSelected={item.id === waterfallItemId}
errorCount={errorCount}
onClick={() => {
onClickWaterfallItem(item);
}}
/>
</WaterfallItemContainer>
<EuiFlexGroup gutterSize="none">
<EuiFlexItem grow={false}>
<ToggleAccordionButton
show={!!children.length}
isOpen={isOpen}
childrenAmount={children.length}
onClick={toggleAccordion}
/>
</EuiFlexItem>
<EuiFlexItem>
<WaterfallItem
key={item.id}
timelineMargins={timelineMargins}
color={item.color}
item={item}
totalDuration={duration}
isSelected={item.id === waterfallItemId}
errorCount={errorCount}
onClick={() => {
onClickWaterfallItem(item);
}}
/>
</EuiFlexItem>
</EuiFlexGroup>
}
arrowDisplay={isEmpty(children) ? 'none' : 'left'}
arrowDisplay="none"
initialIsOpen={true}
forceState={isOpen ? 'open' : 'closed'}
onToggle={() => {
setIsOpen((isCurrentOpen) => !isCurrentOpen);
}}
onToggle={toggleAccordion}
>
{children.map((child) => (
<AccordionWaterfall
Expand All @@ -154,3 +156,40 @@ export function AccordionWaterfall(props: AccordionWaterfallProps) {
</StyledAccordion>
);
}

function ToggleAccordionButton({
show,
isOpen,
childrenAmount,
onClick,
}: {
show: boolean;
isOpen: boolean;
childrenAmount: number;
onClick: () => void;
}) {
if (!show) {
return null;
}

return (
<div style={{ height: ACCORDION_HEIGHT, display: 'flex' }}>
<EuiFlexGroup gutterSize="xs" alignItems="center" justifyContent="center">
<EuiFlexItem grow={false}>
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
<div
onClick={(e: any) => {
e.stopPropagation();
onClick();
}}
>
<EuiIcon type={isOpen ? 'arrowDown' : 'arrowRight'} />
</div>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiText size="xs">{childrenAmount}</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
</div>
);
}

0 comments on commit 0751c78

Please sign in to comment.