Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ interface BaseAction {
id?: string;
}

export type Target = '_blank' | '_self';

export type Action =
| (BaseAction & { onClick: () => void; href?: never })
| (BaseAction & { href: string; onClick?: never });
| (BaseAction & { href: string; onClick?: never; target?: Target });

export interface SectionActionsProps {
actions: Action[];
Expand All @@ -35,7 +37,7 @@ export const SectionActions = ({ actions }: SectionActionsProps) => {
<EuiFlexGroup gutterSize="s" justifyContent="flexEnd" alignItems="center">
{actions.map((action, idx) => {
const { icon, ariaLabel, dataTestSubj, label, onClick, href } = action;
const buttonProps = onClick ? { onClick } : { href };
const buttonProps = onClick ? { onClick } : { href, target: action.target };

return (
<EuiFlexItem grow={false} key={action.id ?? idx} id={action.id}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,10 +402,12 @@ describe('LogsOverview with APM links', () => {
).not.toBeInTheDocument();
});

it('should render trace id link', () => {
expect(
screen.queryByTestId('unifiedDocViewLogsOverviewTraceIdHighlightLink')
).toBeInTheDocument();
it('should render trace id without a link', () => {
const traceId = screen.getByTestId('unifiedDocViewLogsOverviewTraceID');
expect(traceId).toBeInTheDocument();

const traceLink = traceId.querySelector('a');
expect(traceLink).toBeNull();
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { EuiBadge, EuiPanel } from '@elastic/eui';
import type { FieldConfiguration } from '../content_framework';
import { ContentFrameworkTable } from '../content_framework';
import { HighlightField } from '../observability/traces/components/highlight_field';
import { TraceIdLink } from '../observability/traces/components/trace_id_link';
import { fieldLabels } from '../observability/constants';

interface LogsOverviewHighlightsProps
Expand Down Expand Up @@ -93,15 +92,7 @@ const fieldConfigurations: Record<string, FieldConfiguration> = {
[fieldConstants.TRACE_ID_FIELD]: {
title: fieldLabels.TRACE_ID_LABEL,
formatter: (value: unknown, formattedValue: string) => (
<HighlightField value={value as string} formattedValue={formattedValue}>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to keep the highlighting and only remove the link?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah that's true, I'll quickly revert that, thanks 👍🏻

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! Friendly reminder that it doesn't change the demo, because we're using ESQL there 🙇🏻

Screenshot 2026-01-20 at 15 05 42

{({ content }) => (
<TraceIdLink
traceId={value as string}
formattedTraceId={content}
data-test-subj="unifiedDocViewLogsOverviewTraceIdHighlightLink"
/>
)}
</HighlightField>
<HighlightField value={value as string} formattedValue={formattedValue} />
),
},
[fieldConstants.ORCHESTRATOR_CLUSTER_NAME_FIELD]: {
Expand Down Expand Up @@ -135,7 +126,6 @@ const fieldConfigurations: Record<string, FieldConfiguration> = {
},
[fieldConstants.DATASTREAM_NAMESPACE_FIELD]: {
title: fieldLabels.DATASTREAM_NAMESPACE_LABEL,

formatter: (value, formattedValue) => (
<HighlightField value={value as string} formattedValue={formattedValue}>
{({ content }) => <EuiBadge color="hollow">{content}</EuiBadge>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export const OPEN_IN_DISCOVER_LABEL = i18n.translate(
}
);

export const OPEN_IN_DISCOVER_LABEL_ARIAL_LABEL = i18n.translate(
'unifiedDocViewer.observability.traces.openInDiscoverArialLabel',
export const OPEN_IN_DISCOVER_ARIA_LABEL = i18n.translate(

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixing typo ARIAL -> ARIA

'unifiedDocViewer.observability.traces.openInDiscoverAriaLabel',
{ defaultMessage: 'Open in discover link' }
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import { ServiceNameLink } from '../service_name_link';
import { TransactionNameLink } from '../transaction_name_link';
import { HighlightField } from '../highlight_field';
import { DependencyNameLink } from '../dependency_name_link';
import { TraceIdLink } from '../trace_id_link';
import { fieldDescriptions, fieldLabels } from '../../../constants';

export const getSharedFieldConfigurations = (
Expand Down Expand Up @@ -73,15 +72,7 @@ export const getSharedFieldConfigurations = (
[TRACE_ID]: {
title: fieldLabels.TRACE_ID_LABEL,
formatter: (value: unknown, formattedValue: string) => (
<HighlightField value={value as string} formattedValue={formattedValue}>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

{({ content }) => (
<TraceIdLink
traceId={value as string}
formattedTraceId={content}
data-test-subj="unifiedDocViewerObservabilityTracesTraceIdLink"
/>
)}
</HighlightField>
<HighlightField value={value as string} formattedValue={formattedValue} />
),
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { getColumns } from './get_columns';
import { useFetchErrorsByTraceId } from './use_fetch_errors_by_trace_id';
import { useDataSourcesContext } from '../../../../../hooks/use_data_sources';
import { useGetGenerateDiscoverLink } from '../../../../../hooks/use_generate_discover_link';
import { OPEN_IN_DISCOVER_LABEL, OPEN_IN_DISCOVER_LABEL_ARIAL_LABEL } from '../../common/constants';
import { OPEN_IN_DISCOVER_LABEL, OPEN_IN_DISCOVER_ARIA_LABEL } from '../../common/constants';
import { createTraceContextWhereClauseForErrors } from '../../common/create_trace_context_where_clause';
import {
ScrollableSectionWrapper,
Expand Down Expand Up @@ -89,7 +89,7 @@ export const ErrorsTable = forwardRef<ScrollableSectionWrapperApi, Props>(
{
icon: 'discoverApp',
label: OPEN_IN_DISCOVER_LABEL,
ariaLabel: OPEN_IN_DISCOVER_LABEL_ARIAL_LABEL,
ariaLabel: OPEN_IN_DISCOVER_ARIA_LABEL,
href: openInDiscoverLink,
dataTestSubj: 'unifiedDocViewerSpanLinksRefreshButton',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { useDataSourcesContext } from '../../../../../hooks/use_data_sources';
import { useGetGenerateDiscoverLink } from '../../../../../hooks/use_generate_discover_link';
import { getColumns } from './get_columns';
import { useFetchSpanLinks } from './use_fetch_span_links';
import { OPEN_IN_DISCOVER_LABEL, OPEN_IN_DISCOVER_LABEL_ARIAL_LABEL } from '../../common/constants';
import { OPEN_IN_DISCOVER_LABEL, OPEN_IN_DISCOVER_ARIA_LABEL } from '../../common/constants';

export interface Props {
traceId: string;
Expand Down Expand Up @@ -138,7 +138,7 @@ export function SpanLinks({ docId, traceId, processorEvent }: Props) {
{
icon: 'discoverApp',
label: OPEN_IN_DISCOVER_LABEL,
ariaLabel: OPEN_IN_DISCOVER_LABEL_ARIAL_LABEL,
ariaLabel: OPEN_IN_DISCOVER_ARIA_LABEL,
href: openInDiscoverLink,
dataTestSubj: 'unifiedDocViewerSpanLinksRefreshButton',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { useDataSourcesContext } from '../../../../../hooks/use_data_sources';
import { useLogsQuery } from '../../hooks/use_logs_query';
import { useGetGenerateDiscoverLink } from '../../../../../hooks/use_generate_discover_link';
import { createTraceContextWhereClause } from '../../common/create_trace_context_where_clause';
import { OPEN_IN_DISCOVER_LABEL, OPEN_IN_DISCOVER_LABEL_ARIAL_LABEL } from '../../common/constants';
import { OPEN_IN_DISCOVER_LABEL, OPEN_IN_DISCOVER_ARIA_LABEL } from '../../common/constants';

const logsTitle = i18n.translate('unifiedDocViewer.observability.traces.section.logs.title', {
defaultMessage: 'Logs',
Expand Down Expand Up @@ -78,7 +78,7 @@ export function TraceContextLogEvents({
{
icon: 'discoverApp',
label: OPEN_IN_DISCOVER_LABEL,
ariaLabel: OPEN_IN_DISCOVER_LABEL_ARIAL_LABEL,
ariaLabel: OPEN_IN_DISCOVER_ARIA_LABEL,
href: openInDiscoverLink,
dataTestSubj: 'unifiedDocViewerLogsOpenInDiscoverButton',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,23 @@ jest.mock('../../../../..', () => ({
ContentFrameworkSection: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
}));

jest.mock('../../../../../hooks/use_data_sources', () => ({
useDataSourcesContext: () => ({
indexes: {
apm: {
traces: 'traces-apm*',
errors: 'apm-error-*',
},
logs: 'logs-*',
},
}),
}));

jest.mock('../../../../../hooks/use_generate_discover_link', () => ({
useGetGenerateDiscoverLink: () => ({
generateDiscoverLink: jest.fn().mockReturnValue('mock-discover-link'),
}),
}));
describe('TraceWaterfall', () => {
const dataView = createStubDataView({
spec: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@
import { EmbeddableRenderer } from '@kbn/embeddable-plugin/public';
import { i18n } from '@kbn/i18n';
import type { DocViewRenderProps } from '@kbn/unified-doc-viewer/types';
import React, { useCallback, useState } from 'react';
import React, { useCallback, useMemo, useState } from 'react';
import { EuiDelayRender } from '@elastic/eui';
import { css } from '@emotion/react';
import { TRACE_ID_FIELD } from '@kbn/discover-utils';
import type { Target } from '../../../../content_framework/section/section_actions';
import { useGetGenerateDiscoverLink } from '../../../../../hooks/use_generate_discover_link';
import { useDataSourcesContext } from '../../../../../hooks/use_data_sources';
import { ContentFrameworkSection } from '../../../../..';
import { getUnifiedDocViewerServices } from '../../../../../plugin';
import { FullScreenWaterfall } from '../full_screen_waterfall';
import { TraceWaterfallTourStep } from './full_screen_waterfall_tour_step';
import { OPEN_IN_DISCOVER_LABEL, OPEN_IN_DISCOVER_ARIA_LABEL } from '../../common/constants';

interface Props {
traceId: string;
Expand All @@ -40,8 +45,18 @@ const sectionTitle = i18n.translate('unifiedDocViewer.observability.traces.trace

export function TraceWaterfall({ traceId, docId, serviceName, dataView }: Props) {
const { data } = getUnifiedDocViewerServices();
const { indexes } = useDataSourcesContext();
const [showFullScreenWaterfall, setShowFullScreenWaterfall] = useState(false);
const { from: rangeFrom, to: rangeTo } = data.query.timefilter.timefilter.getAbsoluteTime();

const { generateDiscoverLink } = useGetGenerateDiscoverLink({
indexPattern: indexes.apm.traces,
Comment thread
iblancof marked this conversation as resolved.
});

const openInDiscoverLink = useMemo(() => {
return generateDiscoverLink({ [TRACE_ID_FIELD]: traceId });
}, [generateDiscoverLink, traceId]);

const getParentApi = useCallback(
() => ({
getSerializedStateForChild: () => ({
Expand Down Expand Up @@ -76,6 +91,18 @@ export function TraceWaterfall({ traceId, docId, serviceName, dataView }: Props)
title={sectionTitle}
description={sectionTip}
actions={[
...(openInDiscoverLink
? [
{
icon: 'discoverApp',
label: OPEN_IN_DISCOVER_LABEL,
ariaLabel: OPEN_IN_DISCOVER_ARIA_LABEL,
href: openInDiscoverLink,
target: '_blank' as Target,
Comment thread
iblancof marked this conversation as resolved.
Outdated
dataTestSubj: 'unifiedDocViewerObservabilityTracesOpenInDiscoverButton',
},
]
: []),
{
icon: 'fullScreen',
onClick: () => setShowFullScreenWaterfall(true),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8865,7 +8865,6 @@
"visTypeVega.esQueryParser.shiftMustValueTypeErrorMessage": "{shiftParam} muss ein numerischer Wert sein",
"visTypeVega.esQueryParser.timefilterValueErrorMessage": "Die Eigenschaft {timefilter} muss auf {trueValue}, {minValue} oder {maxValue} gesetzt werden",
"visTypeVega.esQueryParser.unknownUnitValueErrorMessage": "Unbekannter {unitParamName}-Wert. Muss eines der folgenden sein: [{unitParamValues}]",
"visTypeVega.queryParser.unnamedRequest": "Unbenannte Anfrage #{index}",
"visTypeVega.esQueryParser.urlBodyValueTypeErrorMessage": "{configName} muss ein Objekt sein",
"visTypeVega.esQueryParser.urlContextAndUrlTimefieldMustNotBeUsedErrorMessage": "{urlContext} und {timefield} dürfen nicht verwendet werden, wenn {queryParam} gesetzt ist.",
"visTypeVega.function.help": "Vega-Visualisierung",
Expand All @@ -8885,6 +8884,7 @@
"visTypeVega.mapView.minZoomAndMaxZoomHaveBeenSwappedWarningMessage": "{minZoomPropertyName} und {maxZoomPropertyName} wurden vertauscht",
"visTypeVega.mapView.resettingPropertyToMaxValueWarningMessage": "Zurücksetzen von {name} auf {max}",
"visTypeVega.mapView.resettingPropertyToMinValueWarningMessage": "Zurücksetzen von {name} auf {min}",
"visTypeVega.queryParser.unnamedRequest": "Unbenannte Anfrage #{index}",
"visTypeVega.type.vegaDescription": "Verwenden Sie die Vega-Syntax, um neue Arten von Visualisierungen zu erstellen.",
"visTypeVega.type.vegaTitleInWizard": "Benutzerdefinierte Visualisierung",
"visTypeVega.urlParser.dataUrlRequiresUrlParameterInFormErrorMessage": "{dataUrlParam} erfordert einen {urlParam}-Parameter in der Form „{formLink}“}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9014,7 +9014,6 @@
"visTypeVega.esQueryParser.shiftMustValueTypeErrorMessage": "{shiftParam} doit être une valeur numérique",
"visTypeVega.esQueryParser.timefilterValueErrorMessage": "La propriété {timefilter} doit être définie sur {trueValue}, {minValue} ou {maxValue}",
"visTypeVega.esQueryParser.unknownUnitValueErrorMessage": "Valeur {unitParamName} inconnue. Doit être l'une des valeurs suivantes : [{unitParamValues}]",
"visTypeVega.queryParser.unnamedRequest": "Requête sans nom #{index}",
"visTypeVega.esQueryParser.urlBodyValueTypeErrorMessage": "{configName} doit être un objet",
"visTypeVega.esQueryParser.urlContextAndUrlTimefieldMustNotBeUsedErrorMessage": "{urlContext} et {timefield} ne doivent pas être utilisés lorsque {queryParam} est défini",
"visTypeVega.function.help": "Visualisation Vega",
Expand All @@ -9034,6 +9033,7 @@
"visTypeVega.mapView.minZoomAndMaxZoomHaveBeenSwappedWarningMessage": "{minZoomPropertyName} et {maxZoomPropertyName} ont été permutés",
"visTypeVega.mapView.resettingPropertyToMaxValueWarningMessage": "Réinitialisation de {name} sur {max}",
"visTypeVega.mapView.resettingPropertyToMinValueWarningMessage": "Réinitialisation de {name} sur {min}",
"visTypeVega.queryParser.unnamedRequest": "Requête sans nom #{index}",
"visTypeVega.type.vegaDescription": "Utilisez la syntaxe Vega pour créer de nouveaux types de visualisations.",
"visTypeVega.type.vegaTitleInWizard": "Visualisation personnalisée",
"visTypeVega.urlParser.dataUrlRequiresUrlParameterInFormErrorMessage": "{dataUrlParam} requiert un paramètre {urlParam} sous la forme \"{formLink}\"",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9025,7 +9025,6 @@
"visTypeVega.esQueryParser.shiftMustValueTypeErrorMessage": "{shiftParam} は数値でなければなりません",
"visTypeVega.esQueryParser.timefilterValueErrorMessage": "{timefilter} のプロパティは {trueValue}、{minValue}、または {maxValue} に設定する必要があります",
"visTypeVega.esQueryParser.unknownUnitValueErrorMessage": "不明な {unitParamName} 値。次のいずれかでなければなりません。[{unitParamValues}]",
"visTypeVega.queryParser.unnamedRequest": "無題のリクエスト#{index}",
"visTypeVega.esQueryParser.urlBodyValueTypeErrorMessage": "{configName} はオブジェクトでなければなりません",
"visTypeVega.esQueryParser.urlContextAndUrlTimefieldMustNotBeUsedErrorMessage": "{urlContext} と {timefield} は {queryParam} が設定されている場合使用できません",
"visTypeVega.function.help": "Vega ビジュアライゼーション",
Expand All @@ -9045,6 +9044,7 @@
"visTypeVega.mapView.minZoomAndMaxZoomHaveBeenSwappedWarningMessage": "{minZoomPropertyName} と {maxZoomPropertyName} が交換されました",
"visTypeVega.mapView.resettingPropertyToMaxValueWarningMessage": "{name} を {max} にリセットしています",
"visTypeVega.mapView.resettingPropertyToMinValueWarningMessage": "{name} を {min} にリセットしています",
"visTypeVega.queryParser.unnamedRequest": "無題のリクエスト#{index}",
"visTypeVega.type.vegaDescription": "Vega構文を使用して、新しいタイプのビジュアライゼーションを作成します。",
"visTypeVega.type.vegaTitleInWizard": "カスタムビジュアライゼーション",
"visTypeVega.urlParser.dataUrlRequiresUrlParameterInFormErrorMessage": "{dataUrlParam} には「{formLink}」の形で {urlParam} パラメーターが必要です",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9015,7 +9015,6 @@
"visTypeVega.esQueryParser.shiftMustValueTypeErrorMessage": "{shiftParam} 必须为数值",
"visTypeVega.esQueryParser.timefilterValueErrorMessage": "{timefilter} 属性必须设置为 {trueValue}、{minValue} 或 {maxValue}",
"visTypeVega.esQueryParser.unknownUnitValueErrorMessage": "{unitParamName} 值未知。必须是以下值之一:[{unitParamValues}]",
"visTypeVega.queryParser.unnamedRequest": "未命名的请求 #{index}",
"visTypeVega.esQueryParser.urlBodyValueTypeErrorMessage": "{configName} 必须为对象",
"visTypeVega.esQueryParser.urlContextAndUrlTimefieldMustNotBeUsedErrorMessage": "设置了 {queryParam} 时,不得使用 {urlContext} 和 {timefield}",
"visTypeVega.function.help": "Vega 可视化",
Expand All @@ -9035,6 +9034,7 @@
"visTypeVega.mapView.minZoomAndMaxZoomHaveBeenSwappedWarningMessage": "已互换 {minZoomPropertyName} 和 {maxZoomPropertyName}",
"visTypeVega.mapView.resettingPropertyToMaxValueWarningMessage": "将 {name} 重置为 {max}",
"visTypeVega.mapView.resettingPropertyToMinValueWarningMessage": "将 {name} 重置为 {min}",
"visTypeVega.queryParser.unnamedRequest": "未命名的请求 #{index}",
"visTypeVega.type.vegaDescription": "使用 Vega 语法创建新的可视化类型。",
"visTypeVega.type.vegaTitleInWizard": "定制可视化",
"visTypeVega.urlParser.dataUrlRequiresUrlParameterInFormErrorMessage": "{dataUrlParam} 需要“{formLink}”形式的 {urlParam} 参数",
Expand Down
Loading