mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[APM] Add icons to timeline (#27840)
* [APM] Add icons to timeline * Update snapshots * Remove unused imports * Decrease font-size * Add inline comments * Fix margin for Legends * Address feedback * Fix snapshot * Fix tslint
This commit is contained in:
parent
277634507f
commit
1b2a5861b4
5 changed files with 78 additions and 51 deletions
|
@ -7,17 +7,9 @@
|
|||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { EuiIcon } from '@elastic/eui';
|
||||
import {
|
||||
colors,
|
||||
fontFamily,
|
||||
fontFamilyCode,
|
||||
fontSize,
|
||||
fontSizes,
|
||||
px,
|
||||
unit,
|
||||
units
|
||||
} from '../../../../../../style/variables';
|
||||
import { EuiIcon, EuiText } from '@elastic/eui';
|
||||
import { asTime } from 'x-pack/plugins/apm/public/utils/formatters';
|
||||
import { colors, px, unit, units } from '../../../../../../style/variables';
|
||||
import { IWaterfallItem } from './waterfall_helpers/waterfall_helpers';
|
||||
|
||||
type ItemType = 'transaction' | 'span';
|
||||
|
@ -40,8 +32,7 @@ const Container = styled<IContainerStyleProps, 'div'>('div')`
|
|||
display: block;
|
||||
user-select: none;
|
||||
padding-top: ${px(units.half)};
|
||||
padding-bottom: ${props =>
|
||||
px(props.type === 'span' ? units.plus + units.quarter : units.plus)};
|
||||
padding-bottom: ${px(units.plus)};
|
||||
margin-right: ${props => px(props.timelineMargins.right)};
|
||||
margin-left: ${props => px(props.timelineMargins.left)};
|
||||
border-top: 1px solid ${colors.gray4};
|
||||
|
@ -60,30 +51,28 @@ const ItemBar = styled<IBarStyleProps, any>('div')`
|
|||
background-color: ${props => props.color};
|
||||
`;
|
||||
|
||||
const ItemLabel = styled.div`
|
||||
white-space: nowrap;
|
||||
const ItemText = styled.span`
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: auto;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: ${px(units.plus)};
|
||||
|
||||
/* add margin to all direct descendants */
|
||||
& > * {
|
||||
margin-right: ${px(units.half)};
|
||||
}
|
||||
`;
|
||||
|
||||
const SpanLabel = styled(ItemLabel)`
|
||||
const SpanNameLabel = styled.span`
|
||||
color: ${colors.gray2};
|
||||
font-weight: normal;
|
||||
font-family: ${fontFamilyCode};
|
||||
font-size: ${fontSizes.small};
|
||||
bottom: ${px(units.half)};
|
||||
white-space: nowrap;
|
||||
`;
|
||||
|
||||
const TransactionLabel = styled(ItemLabel)`
|
||||
const TransactionNameLabel = styled.span`
|
||||
font-weight: 600;
|
||||
font-family: ${fontFamily};
|
||||
font-size: ${fontSize};
|
||||
bottom: ${px(units.quarter)};
|
||||
white-space: nowrap;
|
||||
`;
|
||||
|
||||
interface ITimelineMargins {
|
||||
|
@ -102,18 +91,58 @@ interface IWaterfallItemProps {
|
|||
onClick: () => any;
|
||||
}
|
||||
|
||||
function Prefix({ item }: { item: IWaterfallItem }) {
|
||||
if (item.docType !== 'transaction') {
|
||||
function PrefixIcon({ item }: { item: IWaterfallItem }) {
|
||||
if (item.docType === 'span') {
|
||||
// icon for database spans
|
||||
const isDbType = item.span.span.type.startsWith('db');
|
||||
if (isDbType) {
|
||||
return <EuiIcon type="database" />;
|
||||
}
|
||||
|
||||
// omit icon for other spans
|
||||
return null;
|
||||
}
|
||||
|
||||
// icon for RUM agent transactions
|
||||
const isRumAgent = item.transaction.context.service.agent.name === 'js-base';
|
||||
if (isRumAgent) {
|
||||
return <EuiIcon type="globe" />;
|
||||
}
|
||||
|
||||
// icon for other transactions
|
||||
return <EuiIcon type="merge" />;
|
||||
}
|
||||
|
||||
function Duration({ item }: { item: IWaterfallItem }) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<EuiIcon type="merge" />{' '}
|
||||
</React.Fragment>
|
||||
<EuiText color="subdued" size="xs">
|
||||
{asTime(item.duration)}
|
||||
</EuiText>
|
||||
);
|
||||
}
|
||||
|
||||
function HttpStatusCode({ item }: { item: IWaterfallItem }) {
|
||||
// http status code for transactions of type 'request'
|
||||
const httpStatusCode =
|
||||
item.docType === 'transaction' &&
|
||||
item.transaction.transaction.type === 'request'
|
||||
? item.transaction.transaction.result
|
||||
: undefined;
|
||||
|
||||
if (!httpStatusCode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <EuiText size="xs">{httpStatusCode}</EuiText>;
|
||||
}
|
||||
|
||||
function NameLabel({ item }: { item: IWaterfallItem }) {
|
||||
const StyledLabel =
|
||||
item.docType === 'span' ? SpanNameLabel : TransactionNameLabel;
|
||||
|
||||
return <StyledLabel>{item.name}</StyledLabel>;
|
||||
}
|
||||
|
||||
export function WaterfallItem({
|
||||
timelineMargins,
|
||||
totalDuration,
|
||||
|
@ -128,7 +157,6 @@ export function WaterfallItem({
|
|||
|
||||
const width = (item.duration / totalDuration) * 100;
|
||||
const left = ((item.offset + item.skew) / totalDuration) * 100;
|
||||
const Label = item.docType === 'span' ? SpanLabel : TransactionLabel;
|
||||
|
||||
return (
|
||||
<Container
|
||||
|
@ -142,11 +170,14 @@ export function WaterfallItem({
|
|||
color={color}
|
||||
type={item.docType}
|
||||
/>
|
||||
<Label // using inline styles instead of props to avoid generating a css class for each item
|
||||
<ItemText // using inline styles instead of props to avoid generating a css class for each item
|
||||
style={{ minWidth: `${Math.max(100 - left, 0)}%` }}
|
||||
>
|
||||
<Prefix item={item} /> {item.name}
|
||||
</Label>
|
||||
<PrefixIcon item={item} />
|
||||
<HttpStatusCode item={item} />
|
||||
<NameLabel item={item} />
|
||||
<Duration item={item} />
|
||||
</ItemText>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -22,9 +22,10 @@ const Container = styled.div`
|
|||
align-items: center;
|
||||
justify-content: space-around;
|
||||
flex-wrap: wrap;
|
||||
padding-top: 15px;
|
||||
|
||||
div {
|
||||
/* add margin to all direct descendant divs */
|
||||
& > div {
|
||||
margin-top: ${px(units.half)};
|
||||
margin-right: ${px(unit)};
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
|
|
|
@ -1034,7 +1034,6 @@ Array [
|
|||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.c2 {
|
||||
|
@ -1077,14 +1076,14 @@ Array [
|
|||
-webkit-flex-wrap: wrap;
|
||||
-ms-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.c0 div {
|
||||
.c0 > div {
|
||||
margin-top: 8px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.c0 div:last-child {
|
||||
.c0 > div:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
|
@ -1226,7 +1225,6 @@ Array [
|
|||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.c6 {
|
||||
|
@ -2471,7 +2469,6 @@ Array [
|
|||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.c2 {
|
||||
|
@ -2514,14 +2511,14 @@ Array [
|
|||
-webkit-flex-wrap: wrap;
|
||||
-ms-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.c0 div {
|
||||
.c0 > div {
|
||||
margin-top: 8px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.c0 div:last-child {
|
||||
.c0 > div:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ const Container = styled.div`
|
|||
cursor: ${props => (props.clickable ? 'pointer' : 'initial')};
|
||||
opacity: ${props => (props.disabled ? 0.4 : 1)};
|
||||
user-select: none;
|
||||
padding-bottom: 15px;
|
||||
`;
|
||||
|
||||
export const Indicator = styled.span`
|
||||
|
|
|
@ -18,7 +18,6 @@ exports[`Timeline should render with data 1`] = `
|
|||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.c1 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue