diff --git a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/StickyErrorProperties.test.tsx b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/StickyErrorProperties.test.tsx
deleted file mode 100644
index 4d4991f161f6..000000000000
--- a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/StickyErrorProperties.test.tsx
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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 { shallow, ShallowWrapper } from 'enzyme';
-import React from 'react';
-import { APMError } from '../../../../../typings/es_schemas/ui/APMError';
-import { Transaction } from '../../../../../typings/es_schemas/ui/Transaction';
-import { IStickyProperty } from '../../../shared/StickyProperties';
-import { StickyErrorProperties } from './StickyErrorProperties';
-import {
- ERROR_PAGE_URL,
- URL_FULL
-} from '../../../../../common/elasticsearch_fieldnames';
-
-describe('StickyErrorProperties', () => {
- it('should render StickyProperties', () => {
- const transaction = {
- http: { request: { method: 'GET' } },
- url: { full: 'myUrl' },
- trace: { id: 'traceId' },
- transaction: {
- type: 'myTransactionType',
- name: 'myTransactionName',
- id: 'myTransactionName'
- },
- service: { name: 'myService' },
- user: { id: 'myUserId' }
- } as Transaction;
-
- const error = {
- '@timestamp': 'myTimestamp',
- agent: { name: 'nodejs' },
- http: { request: { method: 'GET' } },
- url: { full: 'myUrl' },
- service: { name: 'myService' },
- user: { id: 'myUserId' },
- error: { exception: [{ handled: true }] },
- transaction: { id: 'myTransactionId', sampled: true }
- } as APMError;
-
- const wrapper = shallow(
-
- );
-
- expect(wrapper).toMatchSnapshot();
- });
-
- it('url.full', () => {
- const error = {
- agent: { name: 'nodejs' },
- url: { full: 'myFullUrl' }
- } as APMError;
-
- const wrapper = shallow(
-
- );
- const urlValue = getValueByFieldName(wrapper, URL_FULL);
- expect(urlValue).toBe('myFullUrl');
- });
-
- it('error.page.url', () => {
- const error = {
- agent: { name: 'rum-js' },
- error: { page: { url: 'myPageUrl' } }
- } as APMError;
-
- const wrapper = shallow(
-
- );
- const urlValue = getValueByFieldName(wrapper, ERROR_PAGE_URL);
- expect(urlValue).toBe('myPageUrl');
- });
-
- describe('error.exception.handled', () => {
- it('should should render "true"', () => {
- const error = {
- agent: { name: 'nodejs' },
- error: { exception: [{ handled: true }] }
- } as APMError;
- const wrapper = shallow(
-
- );
- const value = getValueByFieldName(wrapper, 'error.exception.handled');
- expect(value).toBe('true');
- });
-
- it('should should render "false"', () => {
- const error = {
- agent: { name: 'nodejs' },
- error: { exception: [{ handled: false }] }
- } as APMError;
- const wrapper = shallow(
-
- );
- const value = getValueByFieldName(wrapper, 'error.exception.handled');
- expect(value).toBe('false');
- });
-
- it('should should render "N/A"', () => {
- const error = { agent: { name: 'nodejs' } } as APMError;
- const wrapper = shallow(
-
- );
- const value = getValueByFieldName(wrapper, 'error.exception.handled');
- expect(value).toBe('N/A');
- });
- });
-});
-
-function getValueByFieldName(wrapper: ShallowWrapper, fieldName: string) {
- const stickyProps = wrapper.prop('stickyProperties') as IStickyProperty[];
- const prop = stickyProps.find(p => p.fieldName === fieldName);
- return prop && prop.val;
-}
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/StickyErrorProperties.tsx b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/StickyErrorProperties.tsx
deleted file mode 100644
index 38856618cc53..000000000000
--- a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/StickyErrorProperties.tsx
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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 { i18n } from '@kbn/i18n';
-import { isBoolean } from 'lodash';
-import React, { Fragment } from 'react';
-import { idx } from '@kbn/elastic-idx';
-import {
- ERROR_EXC_HANDLED,
- HTTP_REQUEST_METHOD,
- TRANSACTION_ID,
- URL_FULL,
- USER_ID,
- ERROR_PAGE_URL
-} from '../../../../../common/elasticsearch_fieldnames';
-import { NOT_AVAILABLE_LABEL } from '../../../../../common/i18n';
-import { APMError } from '../../../../../typings/es_schemas/ui/APMError';
-import { Transaction } from '../../../../../typings/es_schemas/ui/Transaction';
-import { StickyProperties } from '../../../shared/StickyProperties';
-import { TransactionDetailLink } from '../../../shared/Links/apm/TransactionDetailLink';
-import { isRumAgentName } from '../../../../../common/agent_name';
-
-interface Props {
- error: APMError;
- transaction: Transaction | undefined;
-}
-
-function TransactionLinkWrapper({
- transaction
-}: {
- transaction: Transaction | undefined;
-}) {
- if (!transaction) {
- return {NOT_AVAILABLE_LABEL};
- }
-
- const isSampled = transaction.transaction.sampled;
- if (!isSampled) {
- return {transaction.transaction.id};
- }
-
- return (
-
- {transaction.transaction.id}
-
- );
-}
-
-export function StickyErrorProperties({ error, transaction }: Props) {
- const isHandled = idx(error, _ => _.error.exception[0].handled);
- const isRumAgent = isRumAgentName(error.agent.name);
-
- const { urlFieldName, urlValue } = isRumAgent
- ? {
- urlFieldName: ERROR_PAGE_URL,
- urlValue: idx(error, _ => _.error.page.url)
- }
- : {
- urlFieldName: URL_FULL,
- urlValue: idx(error, _ => _.url.full)
- };
-
- const stickyProperties = [
- {
- fieldName: '@timestamp',
- label: i18n.translate('xpack.apm.errorGroupDetails.timestampLabel', {
- defaultMessage: 'Timestamp'
- }),
- val: error['@timestamp'],
- width: '50%'
- },
- {
- fieldName: urlFieldName,
- label: 'URL',
- val: urlValue || NOT_AVAILABLE_LABEL,
- truncated: true,
- width: '50%'
- },
- {
- fieldName: HTTP_REQUEST_METHOD,
- label: i18n.translate('xpack.apm.errorGroupDetails.requestMethodLabel', {
- defaultMessage: 'Request method'
- }),
- val: idx(error, _ => _.http.request.method) || NOT_AVAILABLE_LABEL,
- width: '25%'
- },
- {
- fieldName: ERROR_EXC_HANDLED,
- label: i18n.translate('xpack.apm.errorGroupDetails.handledLabel', {
- defaultMessage: 'Handled'
- }),
- val: isBoolean(isHandled) ? String(isHandled) : NOT_AVAILABLE_LABEL,
- width: '25%'
- },
- {
- fieldName: TRANSACTION_ID,
- label: i18n.translate(
- 'xpack.apm.errorGroupDetails.transactionSampleIdLabel',
- {
- defaultMessage: 'Transaction sample ID'
- }
- ),
- val: ,
- width: '25%'
- },
- {
- fieldName: USER_ID,
- label: i18n.translate('xpack.apm.errorGroupDetails.userIdLabel', {
- defaultMessage: 'User ID'
- }),
- val: idx(error, _ => _.user.id) || NOT_AVAILABLE_LABEL,
- width: '25%'
- }
- ];
-
- return ;
-}
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__snapshots__/StickyErrorProperties.test.tsx.snap b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__snapshots__/StickyErrorProperties.test.tsx.snap
deleted file mode 100644
index 74d0880d40fb..000000000000
--- a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__snapshots__/StickyErrorProperties.test.tsx.snap
+++ /dev/null
@@ -1,74 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`StickyErrorProperties should render StickyProperties 1`] = `
-,
- "width": "25%",
- },
- Object {
- "fieldName": "user.id",
- "label": "User ID",
- "val": "myUserId",
- "width": "25%",
- },
- ]
- }
-/>
-`;
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__snapshots__/index.test.tsx.snap
index 39b9e588ce00..2c011c136f00 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__snapshots__/index.test.tsx.snap
+++ b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__snapshots__/index.test.tsx.snap
@@ -4,7 +4,6 @@ exports[`DetailView should render Discover button 1`] = `
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.test.tsx b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.test.tsx
index e3ba548a0152..f263629a40f6 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.test.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.test.tsx
@@ -34,7 +34,9 @@ describe('DetailView', () => {
occurrencesCount: 10,
transaction: undefined,
error: {
- '@timestamp': 'myTimestamp',
+ timestamp: {
+ us: 0
+ },
http: { request: { method: 'GET' } },
url: { full: 'myUrl' },
service: { name: 'myService' },
@@ -56,10 +58,14 @@ describe('DetailView', () => {
expect(wrapper).toMatchSnapshot();
});
- it('should render StickyProperties', () => {
+ it('should render a Summary', () => {
const errorGroup = {
occurrencesCount: 10,
- error: {} as any,
+ error: {
+ timestamp: {
+ us: 0
+ }
+ } as any,
transaction: undefined
};
const wrapper = shallow(
@@ -68,7 +74,7 @@ describe('DetailView', () => {
urlParams={{}}
location={{} as Location}
/>
- ).find('StickyErrorProperties');
+ ).find('Summary');
expect(wrapper.exists()).toBe(true);
});
@@ -78,7 +84,9 @@ describe('DetailView', () => {
occurrencesCount: 10,
transaction: undefined,
error: {
- '@timestamp': 'myTimestamp',
+ timestamp: {
+ us: 0
+ },
service: {},
user: {}
} as any
@@ -100,7 +108,9 @@ describe('DetailView', () => {
occurrencesCount: 10,
transaction: undefined,
error: {
- '@timestamp': 'myTimestamp',
+ timestamp: {
+ us: 0
+ },
context: {}
} as any
};
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx
index 46f1ce1457d6..41ccb6a6c736 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx
@@ -10,7 +10,9 @@ import {
EuiSpacer,
EuiTab,
EuiTabs,
- EuiTitle
+ EuiTitle,
+ EuiIcon,
+ EuiToolTip
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { Location } from 'history';
@@ -21,7 +23,7 @@ import { idx } from '@kbn/elastic-idx';
import { ErrorGroupAPIResponse } from '../../../../../server/lib/errors/get_error_group';
import { APMError } from '../../../../../typings/es_schemas/ui/APMError';
import { IUrlParams } from '../../../../context/UrlParamsContext/types';
-import { px, unit } from '../../../../style/variables';
+import { px, unit, units } from '../../../../style/variables';
import { DiscoverErrorLink } from '../../../shared/Links/DiscoverLinks/DiscoverErrorLink';
import { fromQuery, toQuery } from '../../../shared/Links/url_helpers';
import { history } from '../../../../utils/history';
@@ -33,7 +35,10 @@ import {
getTabs,
logStacktraceTab
} from './ErrorTabs';
-import { StickyErrorProperties } from './StickyErrorProperties';
+import { Summary } from '../../../shared/Summary';
+import { TimestampSummaryItem } from '../../../shared/Summary/TimestampSummaryItem';
+import { HttpInfoSummaryItem } from '../../../shared/Summary/HttpInfoSummaryItem';
+import { TransactionDetailLink } from '../../../shared/Links/apm/TransactionDetailLink';
const HeaderContainer = styled.div`
display: flex;
@@ -42,6 +47,12 @@ const HeaderContainer = styled.div`
margin-bottom: ${px(unit)};
`;
+const TransactionLinkName = styled.div`
+ margin-left: ${px(units.half)};
+ display: inline-block;
+ vertical-align: middle;
+`;
+
interface Props {
errorGroup: ErrorGroupAPIResponse;
urlParams: IUrlParams;
@@ -67,6 +78,12 @@ export function DetailView({ errorGroup, urlParams, location }: Props) {
const tabs = getTabs(error);
const currentTab = getCurrentTab(tabs, urlParams.detailTab);
+ const errorUrl =
+ idx(error, _ => _.error.page.url) || idx(error, _ => _.url.full);
+
+ const method = idx(error, _ => _.http.request.method);
+ const status = idx(error, _ => _.http.response.status_code);
+
return (
@@ -94,7 +111,41 @@ export function DetailView({ errorGroup, urlParams, location }: Props) {
-
+ ,
+ errorUrl && method ? (
+
+ ) : null,
+ transaction && (
+
+
+
+
+ {transaction.transaction.name}
+
+
+
+ )
+ ]}
+ />
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/PercentOfTrace.tsx b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/PercentOfParent.tsx
similarity index 51%
rename from x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/PercentOfTrace.tsx
rename to x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/PercentOfParent.tsx
index bf05d882ea54..813192793b93 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/PercentOfTrace.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/PercentOfParent.tsx
@@ -9,28 +9,30 @@ import { i18n } from '@kbn/i18n';
import { EuiToolTip } from '@elastic/eui';
import { asPercent } from '../../../../utils/formatters';
-interface PercentOfTraceProps {
+interface PercentOfParentProps {
duration: number;
totalDuration?: number;
+ parentType: 'trace' | 'transaction';
}
-export function PercentOfTrace({
+export function PercentOfParent({
duration,
- totalDuration
-}: PercentOfTraceProps) {
+ totalDuration,
+ parentType
+}: PercentOfParentProps) {
totalDuration = totalDuration || duration;
const isOver100 = duration > totalDuration;
- const percentOfTrace = isOver100
+ const percentOfParent = isOver100
? '>100%'
: asPercent(duration, totalDuration, '');
- const percentOfTraceText = i18n.translate(
- 'xpack.apm.transactionDetails.percentOfTrace',
- {
- defaultMessage: '{value} of trace',
- values: { value: percentOfTrace }
- }
- );
+ const percentOfParentText = i18n.translate('xpack.apm.percentOfParent', {
+ defaultMessage:
+ '({value} of {parentType, select, transaction { transaction } trace {trace} })',
+ values: { value: percentOfParent, parentType }
+ });
+
+ const childType = parentType === 'trace' ? 'transaction' : 'span';
return (
<>
@@ -40,14 +42,18 @@ export function PercentOfTrace({
'xpack.apm.transactionDetails.percentOfTraceLabelExplanation',
{
defaultMessage:
- 'The % of trace exceeds 100% because this transaction takes longer than the root transaction.'
+ 'The % of {parentType, select, transaction {transaction} trace {trace} } exceeds 100% because this {childType, select, span {span} transaction {transaction} } takes longer than the root transaction.',
+ values: {
+ parentType,
+ childType
+ }
}
)}
>
- <>{percentOfTraceText}>
+ <>{percentOfParentText}>
) : (
- `(${percentOfTraceText})`
+ percentOfParentText
)}
>
);
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/StickyTransactionProperties.tsx b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/StickyTransactionProperties.tsx
index a9fb18776d58..4a8796da6315 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/StickyTransactionProperties.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/StickyTransactionProperties.tsx
@@ -25,7 +25,7 @@ import {
import { ErrorCountBadge } from './ErrorCountBadge';
import { isRumAgentName } from '../../../../../common/agent_name';
import { fontSize } from '../../../../style/variables';
-import { PercentOfTrace } from './PercentOfTrace';
+import { PercentOfParent } from './PercentOfParent';
interface Props {
transaction: Transaction;
@@ -96,7 +96,13 @@ export function StickyTransactionProperties({
defaultMessage: '% of trace'
}
),
- val: ,
+ val: (
+
+ ),
width: '25%'
},
{
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/Duration.tsx b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/Duration.tsx
deleted file mode 100644
index a22344d9c8ea..000000000000
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/Duration.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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 { i18n } from '@kbn/i18n';
-import { EuiToolTip, EuiText } from '@elastic/eui';
-import styled from 'styled-components';
-import { asTime } from '../../../../../utils/formatters';
-import { PercentOfTrace } from '../PercentOfTrace';
-
-interface DurationProps {
- duration: number;
- totalDuration?: number;
-}
-
-const Span = styled('span')`
- white-space: nowrap;
-`;
-
-export function Duration({ duration, totalDuration }: DurationProps) {
- totalDuration = totalDuration || duration;
- const label = i18n.translate('xpack.apm.transactionDetails.durationLabel', {
- defaultMessage: 'Duration'
- });
-
- return (
-
-
- {asTime(duration)}
- {' '}
-
-
- );
-}
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/Timestamp.tsx b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/Timestamp.tsx
deleted file mode 100644
index 0a3aa4383bac..000000000000
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/Timestamp.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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 moment from 'moment';
-import { EuiToolTip, EuiText } from '@elastic/eui';
-import { i18n } from '@kbn/i18n';
-
-interface TimestampProps {
- transactionTimestamp: string;
-}
-
-export function Timestamp({ transactionTimestamp }: TimestampProps) {
- const timestamp = moment(transactionTimestamp).format(
- 'MMM Do YYYY HH:mm:ss.SSS'
- );
-
- const label = i18n.translate('xpack.apm.transactionDetails.timestampLabel', {
- defaultMessage: 'Timestamp'
- });
-
- return (
-
- {timestamp}
-
- );
-}
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/TraceSummary.tsx b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/TraceSummary.tsx
deleted file mode 100644
index 6f4138d3fcb6..000000000000
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/TraceSummary.tsx
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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 { EuiText, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
-import { idx } from '@kbn/elastic-idx';
-import { i18n } from '@kbn/i18n';
-import styled from 'styled-components';
-import euiLightVars from '@elastic/eui/dist/eui_theme_light.json';
-import { Transaction } from '../../../../../../typings/es_schemas/ui/Transaction';
-import { isRumAgentName } from '../../../../../../common/agent_name';
-import { ErrorCountBadge } from '../ErrorCountBadge';
-import { Duration } from './Duration';
-import { Timestamp } from './Timestamp';
-import { HttpInfo } from './HttpInfo';
-import { Result } from './Result';
-import { px, units } from '../../../../../../public/style/variables';
-
-// TODO: Light/Dark theme (@see https://github.com/elastic/kibana/issues/44840)
-const theme = euiLightVars;
-
-const Item = styled(EuiFlexItem)`
- flex-wrap: nowrap;
- border-right: 1px solid ${theme.euiColorMediumShade};
- padding-right: ${px(units.half)};
-
- &:last-child {
- border-right: none;
- padding-right: 0;
- }
-`;
-
-interface Props {
- errorCount: number;
- totalDuration?: number;
- transaction: Transaction;
-}
-
-export function TraceSummary({
- errorCount,
- totalDuration,
- transaction
-}: Props) {
- const result = idx(transaction, _ => _.transaction.result);
- const isRumAgent = isRumAgentName(transaction.agent.name);
- const url = isRumAgent
- ? idx(transaction, _ => _.transaction.page.url)
- : idx(transaction, _ => _.url.full);
-
- return (
- <>
-
-
- -
-
-
- -
-
-
- {url && (
- -
-
-
- )}
- {result && !url && (
- -
-
-
- )}
- {errorCount > 0 && (
- -
-
-
- {i18n.translate('xpack.apm.transactionDetails.errorCount', {
- defaultMessage:
- '{errorCount, number} {errorCount, plural, one {Error} other {Errors}}',
- values: { errorCount }
- })}
-
-
-
- )}
-
-
- >
- );
-}
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/index.ts b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/index.ts
deleted file mode 100644
index e344d62c8a9f..000000000000
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * 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.
- */
-export { TraceSummary } from './TraceSummary';
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/FlyoutTopLevelProperties.tsx b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/FlyoutTopLevelProperties.tsx
index d463a96685b2..a49a557127be 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/FlyoutTopLevelProperties.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/FlyoutTopLevelProperties.tsx
@@ -35,7 +35,7 @@ export function FlyoutTopLevelProperties({ transaction }: Props) {
{transaction.service.name}
),
- width: '50%'
+ width: '25%'
},
{
label: i18n.translate('xpack.apm.transactionDetails.transactionLabel', {
@@ -53,7 +53,7 @@ export function FlyoutTopLevelProperties({ transaction }: Props) {
{transaction.transaction.name}
),
- width: '50%'
+ width: '25%'
}
];
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/SpanFlyout/StickySpanProperties.tsx b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/SpanFlyout/StickySpanProperties.tsx
index fd2f5bb3d606..12cd9fe86c8c 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/SpanFlyout/StickySpanProperties.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/SpanFlyout/StickySpanProperties.tsx
@@ -6,68 +6,63 @@
import { i18n } from '@kbn/i18n';
import React from 'react';
+import { Transaction } from '../../../../../../../../typings/es_schemas/ui/Transaction';
import {
- SPAN_ACTION,
- SPAN_DURATION,
SPAN_NAME,
- SPAN_SUBTYPE,
- SPAN_TYPE
+ TRANSACTION_NAME,
+ SERVICE_NAME
} from '../../../../../../../../common/elasticsearch_fieldnames';
import { NOT_AVAILABLE_LABEL } from '../../../../../../../../common/i18n';
import { Span } from '../../../../../../../../typings/es_schemas/ui/Span';
-import { asMillis, asPercent } from '../../../../../../../utils/formatters';
import { StickyProperties } from '../../../../../../shared/StickyProperties';
-
-function formatType(type: string) {
- switch (type) {
- case 'db':
- return 'DB';
- case 'hard-navigation':
- return i18n.translate(
- 'xpack.apm.transactionDetails.spanFlyout.spanType.navigationTimingLabel',
- {
- defaultMessage: 'Navigation timing'
- }
- );
- default:
- return type;
- }
-}
-
-function formatSubtype(subtype: string) {
- switch (subtype) {
- case 'mysql':
- return 'MySQL';
- default:
- return subtype;
- }
-}
-
-function getSpanTypes(span: Span) {
- const { type, subtype, action } = span.span;
-
- const [primaryType, subtypeFromType, actionFromType] = type.split('.'); // This is to support 6.x data
-
- return {
- spanType: formatType(primaryType),
- spanSubtype: formatSubtype(subtype || subtypeFromType),
- spanAction: action || actionFromType
- };
-}
+import { TransactionOverviewLink } from '../../../../../../shared/Links/apm/TransactionOverviewLink';
+import { TransactionDetailLink } from '../../../../../../shared/Links/apm/TransactionDetailLink';
interface Props {
span: Span;
- totalDuration?: number;
+ transaction?: Transaction;
}
-export function StickySpanProperties({ span, totalDuration }: Props) {
- if (!totalDuration) {
- return null;
- }
-
+export function StickySpanProperties({ span, transaction }: Props) {
const spanName = span.span.name;
- const spanDuration = span.span.duration.us;
- const { spanType, spanSubtype, spanAction } = getSpanTypes(span);
+ const transactionStickyProperties = transaction
+ ? [
+ {
+ label: i18n.translate('xpack.apm.transactionDetails.serviceLabel', {
+ defaultMessage: 'Service'
+ }),
+ fieldName: SERVICE_NAME,
+ val: (
+
+ {transaction.service.name}
+
+ ),
+ width: '25%'
+ },
+ {
+ label: i18n.translate(
+ 'xpack.apm.transactionDetails.transactionLabel',
+ {
+ defaultMessage: 'Transaction'
+ }
+ ),
+ fieldName: TRANSACTION_NAME,
+ val: (
+
+ {transaction.transaction.name}
+
+ ),
+ width: '25%'
+ }
+ ]
+ : [];
+
const stickyProperties = [
{
label: i18n.translate(
@@ -79,72 +74,10 @@ export function StickySpanProperties({ span, totalDuration }: Props) {
fieldName: SPAN_NAME,
val: spanName || NOT_AVAILABLE_LABEL,
truncated: true,
- width: '50%'
+ width: '25%'
},
- {
- fieldName: SPAN_DURATION,
- label: i18n.translate(
- 'xpack.apm.transactionDetails.spanFlyout.durationLabel',
- {
- defaultMessage: 'Duration'
- }
- ),
- val: asMillis(spanDuration),
- width: '50%'
- },
- {
- label: i18n.translate(
- 'xpack.apm.transactionDetails.spanFlyout.percentOfTransactionLabel',
- {
- defaultMessage: '% of transaction'
- }
- ),
- val: asPercent(spanDuration, totalDuration),
- width: '50%'
- },
- {
- fieldName: SPAN_TYPE,
- label: i18n.translate(
- 'xpack.apm.transactionDetails.spanFlyout.typeLabel',
- {
- defaultMessage: 'Type'
- }
- ),
- val: spanType,
- truncated: true,
- width: '15%'
- }
+ ...transactionStickyProperties
];
- if (spanSubtype) {
- stickyProperties.push({
- fieldName: SPAN_SUBTYPE,
- label: i18n.translate(
- 'xpack.apm.transactionDetails.spanFlyout.subtypeLabel',
- {
- defaultMessage: 'Subtype'
- }
- ),
- val: spanSubtype,
- truncated: true,
- width: '15%'
- });
- }
-
- if (spanAction) {
- stickyProperties.push({
- fieldName: SPAN_ACTION,
- label: i18n.translate(
- 'xpack.apm.transactionDetails.spanFlyout.actionLabel',
- {
- defaultMessage: 'Action'
- }
- ),
- val: spanAction,
- truncated: true,
- width: '15%'
- });
- }
-
return ;
}
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/SpanFlyout/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/SpanFlyout/index.tsx
index a5e87420860e..e0519de87e04 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/SpanFlyout/index.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/SpanFlyout/index.tsx
@@ -15,27 +15,72 @@ import {
EuiPortal,
EuiSpacer,
EuiTabbedContent,
- EuiTitle
+ EuiTitle,
+ EuiBadge,
+ EuiToolTip
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { get, keys } from 'lodash';
import React, { Fragment } from 'react';
import styled from 'styled-components';
import { idx } from '@kbn/elastic-idx';
+import { px, units } from '../../../../../../../style/variables';
+import { Summary } from '../../../../../../shared/Summary';
+import { TimestampSummaryItem } from '../../../../../../shared/Summary/TimestampSummaryItem';
+import { DurationSummaryItem } from '../../../../../../shared/Summary/DurationSummaryItem';
import { Span } from '../../../../../../../../typings/es_schemas/ui/Span';
import { Transaction } from '../../../../../../../../typings/es_schemas/ui/Transaction';
import { DiscoverSpanLink } from '../../../../../../shared/Links/DiscoverLinks/DiscoverSpanLink';
import { Stacktrace } from '../../../../../../shared/Stacktrace';
-import { FlyoutTopLevelProperties } from '../FlyoutTopLevelProperties';
import { ResponsiveFlyout } from '../ResponsiveFlyout';
import { DatabaseContext } from './DatabaseContext';
import { HttpContext } from './HttpContext';
import { StickySpanProperties } from './StickySpanProperties';
+function formatType(type: string) {
+ switch (type) {
+ case 'db':
+ return 'DB';
+ case 'hard-navigation':
+ return i18n.translate(
+ 'xpack.apm.transactionDetails.spanFlyout.spanType.navigationTimingLabel',
+ {
+ defaultMessage: 'Navigation timing'
+ }
+ );
+ default:
+ return type;
+ }
+}
+
+function formatSubtype(subtype: string | undefined) {
+ switch (subtype) {
+ case 'mysql':
+ return 'MySQL';
+ default:
+ return subtype;
+ }
+}
+
+function getSpanTypes(span: Span) {
+ const { type, subtype, action } = span.span;
+
+ return {
+ spanType: formatType(type),
+ spanSubtype: formatSubtype(subtype),
+ spanAction: action
+ };
+}
+
const TagName = styled.div`
font-weight: bold;
`;
+const SpanBadge = styled(EuiBadge)`
+ display: inline-block;
+ margin-right: ${px(units.quarter)};
+`;
+
interface Props {
span?: Span;
parentTransaction?: Transaction;
@@ -62,6 +107,7 @@ export function SpanFlyout({
key,
value: get(spanLabels, key)
}));
+ const spanTypes = getSpanTypes(span);
return (
@@ -96,9 +142,50 @@ export function SpanFlyout({
-
-
-
+
+
+ ,
+ ,
+ <>
+
+ {spanTypes.spanType}
+
+ {spanTypes.spanSubtype && (
+
+
+ {spanTypes.spanSubtype}
+
+
+ )}
+ {spanTypes.spanAction && (
+
+ {spanTypes.spanAction}
+
+ )}
+ >
+ ]}
+ />
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/TransactionFlyout/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/TransactionFlyout/index.tsx
index a857b331065c..db3e43574023 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/TransactionFlyout/index.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/TransactionFlyout/index.tsx
@@ -9,7 +9,6 @@ import {
EuiFlexItem,
EuiFlyoutBody,
EuiFlyoutHeader,
- EuiHorizontalRule,
EuiPortal,
EuiSpacer,
EuiTitle
@@ -18,7 +17,7 @@ import { i18n } from '@kbn/i18n';
import React from 'react';
import { Transaction } from '../../../../../../../../typings/es_schemas/ui/Transaction';
import { TransactionActionMenu } from '../../../../../../shared/TransactionActionMenu/TransactionActionMenu';
-import { StickyTransactionProperties } from '../../../StickyTransactionProperties';
+import { TransactionSummary } from '../../../../../../shared/Summary/TransactionSummary';
import { FlyoutTopLevelProperties } from '../FlyoutTopLevelProperties';
import { ResponsiveFlyout } from '../ResponsiveFlyout';
import { TransactionMetadata } from '../../../../../../shared/MetadataTable/TransactionMetadata';
@@ -82,13 +81,13 @@ export function TransactionFlyout({
-
-
+
-
+
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/index.tsx
index ad83a634bda2..e518751e4153 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/index.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/index.tsx
@@ -25,7 +25,7 @@ import { TransactionActionMenu } from '../../../shared/TransactionActionMenu/Tra
import { TransactionTabs } from './TransactionTabs';
import { IWaterfall } from './WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers';
import { LoadingStatePrompt } from '../../../shared/LoadingStatePrompt';
-import { TraceSummary } from './TraceSummary/TraceSummary';
+import { TransactionSummary } from '../../../shared/Summary/TransactionSummary';
function MaybeViewTraceLink({
transaction,
@@ -165,7 +165,7 @@ export const WaterfallWithSummmary: React.SFC = ({
- {
+ const calculatedTotalDuration =
+ totalDuration === undefined ? duration : totalDuration;
+
+ const label = i18n.translate('xpack.apm.transactionDurationLabel', {
+ defaultMessage: 'Duration'
+ });
+ return (
+ <>
+
+ {asTime(duration)}
+
+
+
+
+
+ >
+ );
+};
+
+export { DurationSummaryItem };
diff --git a/x-pack/legacy/plugins/apm/public/components/shared/Summary/ErrorCountSummaryItem.tsx b/x-pack/legacy/plugins/apm/public/components/shared/Summary/ErrorCountSummaryItem.tsx
new file mode 100644
index 000000000000..9f07c06f6ff5
--- /dev/null
+++ b/x-pack/legacy/plugins/apm/public/components/shared/Summary/ErrorCountSummaryItem.tsx
@@ -0,0 +1,33 @@
+/*
+ * 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 { i18n } from '@kbn/i18n';
+import styled from 'styled-components';
+import { px } from '../../../../../code/public/style/variables';
+import { ErrorCountBadge } from '../../app/TransactionDetails/WaterfallWithSummmary/ErrorCountBadge';
+import { units } from '../../../style/variables';
+
+interface Props {
+ count: number;
+}
+
+const Badge = styled(ErrorCountBadge)`
+ margin-top: ${px(units.eighth)};
+`;
+
+const ErrorCountSummaryItem = ({ count }: Props) => {
+ return (
+
+ {i18n.translate('xpack.apm.transactionDetails.errorCount', {
+ defaultMessage:
+ '{errorCount, number} {errorCount, plural, one {Error} other {Errors}}',
+ values: { errorCount: count }
+ })}
+
+ );
+};
+
+export { ErrorCountSummaryItem };
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/HttpInfo.test.tsx b/x-pack/legacy/plugins/apm/public/components/shared/Summary/HttpInfoSummaryItem/HttpInfoSummaryItem.test.tsx
similarity index 64%
rename from x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/HttpInfo.test.tsx
rename to x-pack/legacy/plugins/apm/public/components/shared/Summary/HttpInfoSummaryItem/HttpInfoSummaryItem.test.tsx
index 26bd54909d32..e87c16b9fd10 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/HttpInfo.test.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/shared/Summary/HttpInfoSummaryItem/HttpInfoSummaryItem.test.tsx
@@ -6,24 +6,26 @@
import React from 'react';
import { shallow, mount } from 'enzyme';
-import { HttpInfo } from './HttpInfo';
-import * as exampleTransactions from './__fixtures__/transactions';
import { palettes } from '@elastic/eui';
-import { cloneDeep, set } from 'lodash';
+import { HttpInfoSummaryItem } from './';
+import * as exampleTransactions from '../__fixtures__/transactions';
-describe('HttpInfo', () => {
+describe('HttpInfoSummaryItem', () => {
describe('render', () => {
const transaction = exampleTransactions.httpOk;
const url = 'https://example.com';
- const props = { transaction, url };
+ const method = 'get';
+ const props = { transaction, url, method, status: 200 };
it('renders', () => {
- expect(() => shallow()).not.toThrowError();
+ expect(() =>
+ shallow()
+ ).not.toThrowError();
});
describe('with status code 200', () => {
it('shows a success color', () => {
- const wrapper = mount();
+ const wrapper = mount();
expect(wrapper.find('HttpStatusBadge EuiBadge').prop('color')).toEqual(
palettes.euiPaletteForStatus.colors[0]
@@ -33,10 +35,9 @@ describe('HttpInfo', () => {
describe('with status code 301', () => {
it('shows a warning color', () => {
- const p = cloneDeep(props);
- set(p, 'transaction.http.response.status_code', 301);
+ const p = { ...props, status: 301 };
- const wrapper = mount();
+ const wrapper = mount();
expect(wrapper.find('HttpStatusBadge EuiBadge').prop('color')).toEqual(
palettes.euiPaletteForStatus.colors[4]
@@ -46,10 +47,9 @@ describe('HttpInfo', () => {
describe('with status code 404', () => {
it('shows a error color', () => {
- const p = cloneDeep(props);
- set(p, 'transaction.http.response.status_code', 404);
+ const p = { ...props, status: 404 };
- const wrapper = mount();
+ const wrapper = mount();
expect(wrapper.find('HttpStatusBadge EuiBadge').prop('color')).toEqual(
palettes.euiPaletteForStatus.colors[9]
@@ -59,10 +59,9 @@ describe('HttpInfo', () => {
describe('with status code 502', () => {
it('shows a error color', () => {
- const p = cloneDeep(props);
- set(p, 'transaction.http.response.status_code', 502);
+ const p = { ...props, status: 502 };
- const wrapper = mount();
+ const wrapper = mount();
expect(wrapper.find('HttpStatusBadge EuiBadge').prop('color')).toEqual(
palettes.euiPaletteForStatus.colors[9]
@@ -72,10 +71,9 @@ describe('HttpInfo', () => {
describe('with some other status code', () => {
it('shows the default color', () => {
- const p = cloneDeep(props);
- set(p, 'transaction.http.response.status_code', 700);
+ const p = { ...props, status: 700 };
- const wrapper = mount();
+ const wrapper = mount();
expect(wrapper.find('HttpStatusBadge EuiBadge').prop('color')).toEqual(
'default'
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/HttpInfo.tsx b/x-pack/legacy/plugins/apm/public/components/shared/Summary/HttpInfoSummaryItem/index.tsx
similarity index 80%
rename from x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/HttpInfo.tsx
rename to x-pack/legacy/plugins/apm/public/components/shared/Summary/HttpInfoSummaryItem/index.tsx
index 477904115b0a..d433dae75a1a 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/HttpInfo.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/shared/Summary/HttpInfoSummaryItem/index.tsx
@@ -8,10 +8,8 @@ import React from 'react';
import { EuiToolTip, EuiBadge } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import styled from 'styled-components';
-import { idx } from '@kbn/elastic-idx/target';
import { palettes } from '@elastic/eui';
-import { Transaction } from '../../../../../../typings/es_schemas/ui/Transaction';
-import { units, px, truncate, unit } from '../../../../../style/variables';
+import { units, px, truncate, unit } from '../../../../style/variables';
import { statusCodes } from './statusCodes';
const statusColors = {
@@ -58,7 +56,8 @@ const Url = styled('span')`
${truncate(px(unit * 24))};
`;
interface HttpInfoProps {
- transaction: Transaction;
+ method: string;
+ status?: number;
url: string;
}
@@ -66,12 +65,7 @@ const Span = styled('span')`
white-space: nowrap;
`;
-export function HttpInfo({ transaction, url }: HttpInfoProps) {
- const method = (
- idx(transaction, _ => _.http.request.method) || ''
- ).toUpperCase();
- const status = idx(transaction, _ => _.http.response.status_code);
-
+export function HttpInfoSummaryItem({ status, method, url }: HttpInfoProps) {
const methodLabel = i18n.translate(
'xpack.apm.transactionDetails.requestMethodLabel',
{
@@ -83,7 +77,7 @@ export function HttpInfo({ transaction, url }: HttpInfoProps) {
- {method}
+ <>{method.toUpperCase()}>
{' '}
{url}
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/statusCodes.ts b/x-pack/legacy/plugins/apm/public/components/shared/Summary/HttpInfoSummaryItem/statusCodes.ts
similarity index 100%
rename from x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/statusCodes.ts
rename to x-pack/legacy/plugins/apm/public/components/shared/Summary/HttpInfoSummaryItem/statusCodes.ts
diff --git a/x-pack/legacy/plugins/apm/public/components/shared/Summary/TimestampSummaryItem.tsx b/x-pack/legacy/plugins/apm/public/components/shared/Summary/TimestampSummaryItem.tsx
new file mode 100644
index 000000000000..8d619d94067c
--- /dev/null
+++ b/x-pack/legacy/plugins/apm/public/components/shared/Summary/TimestampSummaryItem.tsx
@@ -0,0 +1,26 @@
+/*
+ * 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 { EuiToolTip } from '@elastic/eui';
+import moment from 'moment-timezone';
+
+interface Props {
+ time: number;
+}
+
+const TimestampSummaryItem = (props: Props) => {
+ const time = moment.tz(props.time, moment.tz.guess());
+ const relativeTimeLabel = time.fromNow();
+ const absoluteTimeLabel = time.format('MMM Do YYYY HH:mm:ss.SSS zz');
+
+ return (
+
+ <>{relativeTimeLabel}>
+
+ );
+};
+
+export { TimestampSummaryItem };
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/Result.tsx b/x-pack/legacy/plugins/apm/public/components/shared/Summary/TransactionResultSummaryItem.tsx
similarity index 79%
rename from x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/Result.tsx
rename to x-pack/legacy/plugins/apm/public/components/shared/Summary/TransactionResultSummaryItem.tsx
index 635282145e66..34a78982f7f2 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/Result.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/shared/Summary/TransactionResultSummaryItem.tsx
@@ -8,11 +8,11 @@ import React from 'react';
import { EuiToolTip, EuiBadge } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-interface ResultProps {
- result: string;
+interface Props {
+ transactionResult: string;
}
-export function Result({ result }: ResultProps) {
+export function TransactionResultSummaryItem({ transactionResult }: Props) {
return (
- {result}
+ {transactionResult}
);
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/TraceSummary.test.tsx b/x-pack/legacy/plugins/apm/public/components/shared/Summary/TransactionSummary.test.tsx
similarity index 68%
rename from x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/TraceSummary.test.tsx
rename to x-pack/legacy/plugins/apm/public/components/shared/Summary/TransactionSummary.test.tsx
index 3a2d0e299a05..19f626187cdd 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/TraceSummary.test.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/shared/Summary/TransactionSummary.test.tsx
@@ -5,12 +5,12 @@
*/
import { shallow } from 'enzyme';
-import { TraceSummary } from '.';
import React from 'react';
-import { Transaction } from '../../../../../../typings/es_schemas/ui/Transaction';
+import { TransactionSummary } from './TransactionSummary';
+import { Transaction } from '../../../../typings/es_schemas/ui/Transaction';
import * as exampleTransactions from './__fixtures__/transactions';
-describe('TraceSummary', () => {
+describe('TransactionSummary', () => {
describe('render', () => {
const transaction: Transaction = exampleTransactions.httpOk;
@@ -21,7 +21,9 @@ describe('TraceSummary', () => {
};
it('renders', () => {
- expect(() => shallow()).not.toThrowError();
+ expect(() =>
+ shallow()
+ ).not.toThrowError();
});
});
});
diff --git a/x-pack/legacy/plugins/apm/public/components/shared/Summary/TransactionSummary.tsx b/x-pack/legacy/plugins/apm/public/components/shared/Summary/TransactionSummary.tsx
new file mode 100644
index 000000000000..aea7e3ef2d38
--- /dev/null
+++ b/x-pack/legacy/plugins/apm/public/components/shared/Summary/TransactionSummary.tsx
@@ -0,0 +1,63 @@
+/*
+ * 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 { idx } from '@kbn/elastic-idx';
+import { Transaction } from '../../../../typings/es_schemas/ui/Transaction';
+import { Summary } from './';
+import { TimestampSummaryItem } from './TimestampSummaryItem';
+import { DurationSummaryItem } from './DurationSummaryItem';
+import { ErrorCountSummaryItem } from './ErrorCountSummaryItem';
+import { isRumAgentName } from '../../../../common/agent_name';
+import { HttpInfoSummaryItem } from './HttpInfoSummaryItem';
+import { TransactionResultSummaryItem } from './TransactionResultSummaryItem';
+
+interface Props {
+ transaction: Transaction;
+ totalDuration: number | undefined;
+ errorCount: number;
+}
+
+const getTransactionResultSummaryItem = (transaction: Transaction) => {
+ const result = idx(transaction, _ => _.transaction.result);
+ const isRumAgent = isRumAgentName(transaction.agent.name);
+ const url = isRumAgent
+ ? idx(transaction, _ => _.transaction.page.url)
+ : idx(transaction, _ => _.url.full);
+
+ if (url) {
+ const method = idx(transaction, _ => _.http.request.method) || '';
+ const status = idx(transaction, _ => _.http.response.status_code);
+
+ return ;
+ }
+
+ if (result) {
+ return ;
+ }
+
+ return null;
+};
+
+const TransactionSummary = ({
+ transaction,
+ totalDuration,
+ errorCount
+}: Props) => {
+ const items = [
+ ,
+ ,
+ getTransactionResultSummaryItem(transaction),
+ errorCount ? : null
+ ];
+
+ return ;
+};
+
+export { TransactionSummary };
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/__fixtures__/transactions.ts b/x-pack/legacy/plugins/apm/public/components/shared/Summary/__fixtures__/transactions.ts
similarity index 89%
rename from x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/__fixtures__/transactions.ts
rename to x-pack/legacy/plugins/apm/public/components/shared/Summary/__fixtures__/transactions.ts
index 06f36dfa18ff..59496dad1657 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TraceSummary/__fixtures__/transactions.ts
+++ b/x-pack/legacy/plugins/apm/public/components/shared/Summary/__fixtures__/transactions.ts
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { Transaction } from '../../../../../../../typings/es_schemas/ui/Transaction';
+import { Transaction } from '../../../../../typings/es_schemas/ui/Transaction';
export const httpOk: Transaction = {
'@timestamp': '0',
diff --git a/x-pack/legacy/plugins/apm/public/components/shared/Summary/index.tsx b/x-pack/legacy/plugins/apm/public/components/shared/Summary/index.tsx
new file mode 100644
index 000000000000..c4b750a360ef
--- /dev/null
+++ b/x-pack/legacy/plugins/apm/public/components/shared/Summary/index.tsx
@@ -0,0 +1,46 @@
+/*
+ * 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 { EuiFlexGrid, EuiFlexItem } from '@elastic/eui';
+import styled from 'styled-components';
+import euiLightVars from '@elastic/eui/dist/eui_theme_light.json';
+import { px, units } from '../../../../public/style/variables';
+
+interface Props {
+ items: Array;
+}
+
+// TODO: Light/Dark theme (@see https://github.com/elastic/kibana/issues/44840)
+const theme = euiLightVars;
+
+const Item = styled(EuiFlexItem)`
+ flex-wrap: nowrap;
+ border-right: 1px solid ${theme.euiColorLightShade};
+ padding-right: ${px(units.half)};
+ flex-flow: row nowrap;
+ line-height: 1.5;
+ align-items: center !important;
+ &:last-child {
+ border-right: none;
+ padding-right: 0;
+ }
+`;
+
+const Summary = ({ items }: Props) => {
+ const filteredItems = items.filter(Boolean) as React.ReactElement[];
+
+ return (
+
+ {filteredItems.map((item, index) => (
+ -
+ {item}
+
+ ))}
+
+ );
+};
+
+export { Summary };
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 2d95899c7099..bdc53e494ec0 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -3315,17 +3315,12 @@
"xpack.apm.errorGroupDetails.errorGroupTitle": "エラーグループ {errorGroupId}",
"xpack.apm.errorGroupDetails.errorOccurrenceTitle": "エラーのオカレンス",
"xpack.apm.errorGroupDetails.exceptionMessageLabel": "例外メッセージ",
- "xpack.apm.errorGroupDetails.handledLabel": "対応済み",
"xpack.apm.errorGroupDetails.logMessageLabel": "ログメッセージ",
"xpack.apm.errorGroupDetails.noErrorsLabel": "エラーが見つかりませんでした",
"xpack.apm.errorGroupDetails.occurrencesChartLabel": "オカレンス",
"xpack.apm.errorGroupDetails.occurrencesLongLabel": "{occCount} 件",
"xpack.apm.errorGroupDetails.occurrencesShortLabel": "{occCount} 件",
- "xpack.apm.errorGroupDetails.requestMethodLabel": "リクエストメソド",
- "xpack.apm.errorGroupDetails.timestampLabel": "タイムスタンプ",
- "xpack.apm.errorGroupDetails.transactionSampleIdLabel": "トランザクションサンプル ID",
"xpack.apm.errorGroupDetails.unhandledLabel": "未対応",
- "xpack.apm.errorGroupDetails.userIdLabel": "ユーザー ID",
"xpack.apm.errorGroupDetails.viewOccurrencesInDiscoverButtonLabel": "ディスカバリで {occurrencesCount} 件のオカレンスを表示",
"xpack.apm.errorsTable.errorMessageAndCulpritColumnLabel": "エラーメッセージと原因",
"xpack.apm.errorsTable.groupIdColumnLabel": "グループ ID",
@@ -3494,16 +3489,11 @@
"xpack.apm.transactionDetails.resultLabel": "結果",
"xpack.apm.transactionDetails.serviceLabel": "サービス",
"xpack.apm.transactionDetails.servicesTitle": "サービス",
- "xpack.apm.transactionDetails.spanFlyout.actionLabel": "アクション",
"xpack.apm.transactionDetails.spanFlyout.databaseStatementTitle": "データベースステートメント",
- "xpack.apm.transactionDetails.spanFlyout.durationLabel": "期間",
"xpack.apm.transactionDetails.spanFlyout.nameLabel": "名前",
- "xpack.apm.transactionDetails.spanFlyout.percentOfTransactionLabel": "トランザクションの %",
"xpack.apm.transactionDetails.spanFlyout.spanDetailsTitle": "スパン詳細",
"xpack.apm.transactionDetails.spanFlyout.spanType.navigationTimingLabel": "ナビゲーションタイミング",
"xpack.apm.transactionDetails.spanFlyout.stackTraceTabLabel": "スタックトレース",
- "xpack.apm.transactionDetails.spanFlyout.subtypeLabel": "サブタイプ",
- "xpack.apm.transactionDetails.spanFlyout.typeLabel": "タイプ",
"xpack.apm.transactionDetails.spanFlyout.viewSpanInDiscoverButtonLabel": "ディスカバリでスパンを表示",
"xpack.apm.transactionDetails.timestampLabel": "タイムスタンプ",
"xpack.apm.transactionDetails.transactionLabel": "トランザクション",
@@ -11572,4 +11562,4 @@
"xpack.fileUpload.fileParser.noFileProvided": "エラー、ファイルが提供されていません",
"xpack.fileUpload.jsonIndexFilePicker.errorGettingIndexName": "インデックス名の取得中にエラーが発生: {errorMessage}"
}
-}
\ No newline at end of file
+}
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 2214faea0725..2bde77133f75 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -3316,17 +3316,12 @@
"xpack.apm.errorGroupDetails.errorGroupTitle": "错误组 {errorGroupId}",
"xpack.apm.errorGroupDetails.errorOccurrenceTitle": "错误发生",
"xpack.apm.errorGroupDetails.exceptionMessageLabel": "异常消息",
- "xpack.apm.errorGroupDetails.handledLabel": "已处理",
"xpack.apm.errorGroupDetails.logMessageLabel": "日志消息",
"xpack.apm.errorGroupDetails.noErrorsLabel": "未找到任何错误",
"xpack.apm.errorGroupDetails.occurrencesChartLabel": "发生次数",
"xpack.apm.errorGroupDetails.occurrencesLongLabel": "{occCount} 次发生",
"xpack.apm.errorGroupDetails.occurrencesShortLabel": "{occCount} 次发生",
- "xpack.apm.errorGroupDetails.requestMethodLabel": "请求方法",
- "xpack.apm.errorGroupDetails.timestampLabel": "时间戳",
- "xpack.apm.errorGroupDetails.transactionSampleIdLabel": "事务样例 ID",
"xpack.apm.errorGroupDetails.unhandledLabel": "未处理",
- "xpack.apm.errorGroupDetails.userIdLabel": "用户 ID",
"xpack.apm.errorGroupDetails.viewOccurrencesInDiscoverButtonLabel": "在 Discover 中查看 {occurrencesCount} 次发生",
"xpack.apm.errorsTable.errorMessageAndCulpritColumnLabel": "错误消息和原因",
"xpack.apm.errorsTable.groupIdColumnLabel": "组 ID",
@@ -3495,16 +3490,11 @@
"xpack.apm.transactionDetails.resultLabel": "结果",
"xpack.apm.transactionDetails.serviceLabel": "服务",
"xpack.apm.transactionDetails.servicesTitle": "服务",
- "xpack.apm.transactionDetails.spanFlyout.actionLabel": "操作",
"xpack.apm.transactionDetails.spanFlyout.databaseStatementTitle": "数据库语句",
- "xpack.apm.transactionDetails.spanFlyout.durationLabel": "持续时间",
"xpack.apm.transactionDetails.spanFlyout.nameLabel": "名称",
- "xpack.apm.transactionDetails.spanFlyout.percentOfTransactionLabel": "事务的 %",
"xpack.apm.transactionDetails.spanFlyout.spanDetailsTitle": "跨度详情",
"xpack.apm.transactionDetails.spanFlyout.spanType.navigationTimingLabel": "导航定时",
"xpack.apm.transactionDetails.spanFlyout.stackTraceTabLabel": "堆栈追溯",
- "xpack.apm.transactionDetails.spanFlyout.subtypeLabel": "子类型",
- "xpack.apm.transactionDetails.spanFlyout.typeLabel": "类型",
"xpack.apm.transactionDetails.spanFlyout.viewSpanInDiscoverButtonLabel": "在 Discover 中查看跨度",
"xpack.apm.transactionDetails.timestampLabel": "时间戳",
"xpack.apm.transactionDetails.transactionLabel": "事务",
@@ -11574,4 +11564,4 @@
"xpack.fileUpload.fileParser.noFileProvided": "错误,未提供任何文件",
"xpack.fileUpload.jsonIndexFilePicker.errorGettingIndexName": "检索索引名称时出错:{errorMessage}"
}
-}
\ No newline at end of file
+}