diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/accordion_waterfall.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/accordion_waterfall.tsx index 9bb8c04eb8bce9..fed52b3bd995b1 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/accordion_waterfall.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/accordion_waterfall.tsx @@ -34,7 +34,10 @@ interface AccordionWaterfallProps { waterfallItemId?: string; waterfall: IWaterfall; timelineMargins: Margins; - onClickWaterfallItem: (item: IWaterfallSpanOrTransaction) => void; + onClickWaterfallItem: ( + item: IWaterfallSpanOrTransaction, + flyoutDetailTab: string + ) => void; showCriticalPath: boolean; maxLevelOpen: number; } @@ -159,8 +162,8 @@ export function AccordionWaterfall(props: AccordionWaterfallProps) { isSelected={item.id === waterfallItemId} errorCount={errorCount} marginLeftLevel={marginLeftLevel} - onClick={() => { - onClickWaterfallItem(item); + onClick={(flyoutDetailTab: string) => { + onClickWaterfallItem(item, flyoutDetailTab); }} segments={criticalPathSegmentsById[item.id] ?.filter((segment) => segment.self) diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/badge/span_links_badge.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/badge/span_links_badge.tsx index 194c3ec38bc9e8..a0ff21afc39801 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/badge/span_links_badge.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/badge/span_links_badge.tsx @@ -9,13 +9,21 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import { SpanLinksCount } from '../waterfall_helpers/waterfall_helpers'; -type Props = SpanLinksCount & { id: string }; +type Props = SpanLinksCount & { + id: string; + onClick: (flyoutDetailTab: string) => unknown; +}; -export function SpanLinksBadge({ linkedParents, linkedChildren, id }: Props) { +export function SpanLinksBadge({ + linkedParents, + linkedChildren, + id, + onClick, +}: Props) { if (!linkedParents && !linkedChildren) { return null; } - + const spanLinksFlyoutTab = 'span_links'; const total = linkedParents + linkedChildren; return ( } > - + { + e.stopPropagation(); + onClick(spanLinksFlyoutTab); + }} + onClickAriaLabel={i18n.translate( + 'xpack.apm.waterfall.spanLinks.badgeAriaLabel', + { + defaultMessage: 'Open span links details', + } + )} + > {i18n.translate('xpack.apm.waterfall.spanLinks.badge', { defaultMessage: '{total} {total, plural, one {Span link} other {Span links}}', diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/index.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/index.tsx index 71a7135c1df71b..191b38f73754a5 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/index.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/index.tsx @@ -31,15 +31,17 @@ const Container = euiStyled.div` const toggleFlyout = ({ history, item, + flyoutDetailTab, }: { history: History; item?: IWaterfallItem; + flyoutDetailTab?: string; }) => { history.replace({ ...history.location, search: fromQuery({ ...toQuery(location.search), - flyoutDetailTab: undefined, + flyoutDetailTab, waterfallItemId: item?.id, }), }); @@ -152,9 +154,10 @@ export function Waterfall({ duration={duration} waterfall={waterfall} timelineMargins={timelineMargins} - onClickWaterfallItem={(item: IWaterfallItem) => - toggleFlyout({ history, item }) - } + onClickWaterfallItem={( + item: IWaterfallItem, + flyoutDetailTab: string + ) => toggleFlyout({ history, item, flyoutDetailTab })} showCriticalPath={showCriticalPath} maxLevelOpen={maxLevelOpen} /> diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/span_flyout/index.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/span_flyout/index.tsx index d298891fb92d53..0bde5cede84502 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/span_flyout/index.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/span_flyout/index.tsx @@ -92,6 +92,7 @@ interface Props { traceId: string; totalDuration?: number; spanLinksCount: SpanLinksCount; + flyoutDetailTab?: string; onClose: () => void; } @@ -107,6 +108,7 @@ export function SpanFlyout({ totalDuration, onClose, spanLinksCount, + flyoutDetailTab, }: Props) { const { data = INITIAL_DATA, status } = useFetcher( (callApmApi) => { @@ -171,6 +173,7 @@ export function SpanFlyout({ parentTransaction={parentTransaction} totalDuration={totalDuration} spanLinksCount={spanLinksCount} + flyoutDetailTab={flyoutDetailTab} /> )} @@ -184,11 +187,13 @@ function SpanFlyoutBody({ parentTransaction, totalDuration, spanLinksCount, + flyoutDetailTab, }: { span: Span; parentTransaction?: Transaction; totalDuration?: number; spanLinksCount: SpanLinksCount; + flyoutDetailTab?: string; }) { const stackframes = span.span.stacktrace; const codeLanguage = parentTransaction?.service.language?.name; @@ -205,6 +210,46 @@ function SpanFlyoutBody({ spanId: span.span.id, processorEvent: ProcessorEvent.span, }); + + const tabs = [ + { + id: 'metadata', + name: i18n.translate('xpack.apm.propertiesTable.tabs.metadataLabel', { + defaultMessage: 'Metadata', + }), + content: ( + + + + + ), + }, + ...(!isEmpty(stackframes) + ? [ + { + id: 'stack-trace', + name: i18n.translate( + 'xpack.apm.transactionDetails.spanFlyout.stackTraceTabLabel', + { + defaultMessage: 'Stack Trace', + } + ), + content: ( + + + + + ), + }, + ] + : []), + ...(spanLinksTabContent ? [spanLinksTabContent] : []), + ]; + + const initialTab = tabs.find(({ id }) => id === flyoutDetailTab) ?? tabs[0]; return ( <> @@ -270,48 +315,7 @@ function SpanFlyoutBody({ /> - - - - - ), - }, - ...(!isEmpty(stackframes) - ? [ - { - id: 'stack-trace', - name: i18n.translate( - 'xpack.apm.transactionDetails.spanFlyout.stackTraceTabLabel', - { - defaultMessage: 'Stack Trace', - } - ), - content: ( - - - - - ), - }, - ] - : []), - ...(spanLinksTabContent ? [spanLinksTabContent] : []), - ]} - /> + ); } diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/transaction_flyout/index.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/transaction_flyout/index.tsx index cf3f5652b24a4e..da53126636a273 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/transaction_flyout/index.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/transaction_flyout/index.tsx @@ -38,6 +38,7 @@ interface Props { errorCount?: number; rootTransactionDuration?: number; spanLinksCount: SpanLinksCount; + flyoutDetailTab?: string; } export function TransactionFlyout({ @@ -47,6 +48,7 @@ export function TransactionFlyout({ errorCount = 0, rootTransactionDuration, spanLinksCount, + flyoutDetailTab, }: Props) { const { data: transaction, status } = useFetcher( (callApmApi) => { @@ -96,6 +98,7 @@ export function TransactionFlyout({ errorCount={errorCount} rootTransactionDuration={rootTransactionDuration} spanLinksCount={spanLinksCount} + flyoutDetailTab={flyoutDetailTab} /> )} @@ -109,11 +112,13 @@ function TransactionFlyoutBody({ errorCount, rootTransactionDuration, spanLinksCount, + flyoutDetailTab, }: { transaction: Transaction; errorCount: number; rootTransactionDuration?: number; spanLinksCount: SpanLinksCount; + flyoutDetailTab?: string; }) { const spanLinksTabContent = getSpanLinksTabContent({ spanLinksCount, @@ -122,6 +127,24 @@ function TransactionFlyoutBody({ processorEvent: ProcessorEvent.transaction, }); + const tabs = [ + { + id: 'metadata', + name: i18n.translate('xpack.apm.propertiesTable.tabs.metadataLabel', { + defaultMessage: 'Metadata', + }), + content: ( + <> + + + + ), + }, + ...(spanLinksTabContent ? [spanLinksTabContent] : []), + ]; + + const initialTab = tabs.find(({ id }) => id === flyoutDetailTab) ?? tabs[0]; + return ( <> @@ -134,28 +157,7 @@ function TransactionFlyoutBody({ /> - - - - - ), - }, - ...(spanLinksTabContent ? [spanLinksTabContent] : []), - ]} - /> + ); } diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_flyout.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_flyout.tsx index db8460f23a6cf4..4704828353b29a 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_flyout.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_flyout.tsx @@ -8,6 +8,7 @@ import { History } from 'history'; import React from 'react'; import { useHistory } from 'react-router-dom'; +import { useApmParams } from '../../../../../../hooks/use_apm_params'; import { SpanFlyout } from './span_flyout'; import { TransactionFlyout } from './transaction_flyout'; import { IWaterfall } from './waterfall_helpers/waterfall_helpers'; @@ -15,7 +16,13 @@ import { IWaterfall } from './waterfall_helpers/waterfall_helpers'; interface Props { waterfallItemId?: string; waterfall: IWaterfall; - toggleFlyout: ({ history }: { history: History }) => void; + toggleFlyout: ({ + history, + flyoutDetailTab, + }: { + history: History; + flyoutDetailTab?: string; + }) => void; } export function WaterfallFlyout({ @@ -24,6 +31,9 @@ export function WaterfallFlyout({ toggleFlyout, }: Props) { const history = useHistory(); + const { + query: { flyoutDetailTab }, + } = useApmParams('/services/{serviceName}/transactions/view'); const currentItem = waterfall.items.find( (item) => item.id === waterfallItemId ); @@ -47,6 +57,7 @@ export function WaterfallFlyout({ traceId={currentItem.doc.trace.id} onClose={() => toggleFlyout({ history })} spanLinksCount={currentItem.spanLinksCount} + flyoutDetailTab={flyoutDetailTab} /> ); case 'transaction': @@ -58,6 +69,7 @@ export function WaterfallFlyout({ rootTransactionDuration={waterfall.rootWaterfallTransaction?.duration} errorCount={waterfall.getErrorCount(currentItem.id)} spanLinksCount={currentItem.spanLinksCount} + flyoutDetailTab={flyoutDetailTab} /> ); default: diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_item.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_item.tsx index 416e46a6101aae..39ad6f4945dff0 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_item.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_item.tsx @@ -122,7 +122,7 @@ interface IWaterfallItemProps { width: number; color: string; }>; - onClick: () => unknown; + onClick: (flyoutDetailTab: string) => unknown; } function PrefixIcon({ item }: { item: IWaterfallSpanOrTransaction }) { @@ -254,6 +254,8 @@ export function WaterfallItem({ const isServerlessColdstart = item.docType === 'transaction' && item.doc.faas?.coldstart; + const waterfallItemFlyoutTab = 'metadata'; + return ( { e.stopPropagation(); - onClick(); + onClick(waterfallItemFlyoutTab); }} > {isServerlessColdstart && } diff --git a/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx b/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx index 2964cd7b7934c1..d2e84cf8e4a851 100644 --- a/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx @@ -186,6 +186,7 @@ export const serviceDetail = { t.partial({ traceId: t.string, transactionId: t.string, + flyoutDetailTab: t.string, }), offsetRt, ]),