mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Tempo / Trace Viewer: Support Span Links in Trace Viewer (#45632)
* Support Span Links in Trace Viewer * Update ReferencesButton styles * Remove datasource prop Co-authored-by: Connor Lindsey <cblindsey3@gmail.com>
This commit is contained in:
@@ -14,16 +14,15 @@
|
||||
|
||||
import React from 'react';
|
||||
import { css } from '@emotion/css';
|
||||
import { stylesFactory, Tooltip } from '@grafana/ui';
|
||||
import { Tooltip, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { TraceSpanReference } from '../types/trace';
|
||||
import ReferenceLink from '../url/ReferenceLink';
|
||||
|
||||
export const getStyles = stylesFactory(() => {
|
||||
export const getStyles = () => {
|
||||
return {
|
||||
MultiParent: css`
|
||||
padding: 0 5px;
|
||||
color: #000;
|
||||
& ~ & {
|
||||
margin-left: 5px;
|
||||
}
|
||||
@@ -39,7 +38,7 @@ export const getStyles = stylesFactory(() => {
|
||||
max-width: none;
|
||||
`,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
type TReferencesButtonProps = {
|
||||
references: TraceSpanReference[];
|
||||
@@ -48,19 +47,19 @@ type TReferencesButtonProps = {
|
||||
focusSpan: (spanID: string) => void;
|
||||
};
|
||||
|
||||
export default class ReferencesButton extends React.PureComponent<TReferencesButtonProps> {
|
||||
render() {
|
||||
const { references, children, tooltipText, focusSpan } = this.props;
|
||||
const styles = getStyles();
|
||||
const ReferencesButton = (props: TReferencesButtonProps) => {
|
||||
const { references, children, tooltipText, focusSpan } = props;
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
// TODO: handle multiple items with some dropdown
|
||||
const ref = references[0];
|
||||
return (
|
||||
<Tooltip content={tooltipText}>
|
||||
<ReferenceLink reference={ref} focusSpan={focusSpan} className={styles.MultiParent}>
|
||||
{children}
|
||||
</ReferenceLink>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
}
|
||||
// TODO: handle multiple items with some dropdown
|
||||
const ref = references[0];
|
||||
return (
|
||||
<Tooltip content={tooltipText}>
|
||||
<ReferenceLink reference={ref} focusSpan={focusSpan} className={styles.MultiParent}>
|
||||
{children}
|
||||
</ReferenceLink>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
export default ReferencesButton;
|
||||
|
||||
@@ -54,6 +54,7 @@ describe('<SpanBarRow>', () => {
|
||||
},
|
||||
spanID,
|
||||
logs: [],
|
||||
references: [],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -84,29 +85,27 @@ describe('<SpanBarRow>', () => {
|
||||
});
|
||||
|
||||
it('render references button', () => {
|
||||
const span = Object.assign(
|
||||
{
|
||||
references: [
|
||||
{
|
||||
refType: 'CHILD_OF',
|
||||
traceID: 'trace1',
|
||||
const newSpan = Object.assign({}, props.span);
|
||||
const span = Object.assign(newSpan, {
|
||||
references: [
|
||||
{
|
||||
refType: 'CHILD_OF',
|
||||
traceID: 'trace1',
|
||||
spanID: 'span0',
|
||||
span: {
|
||||
spanID: 'span0',
|
||||
span: {
|
||||
spanID: 'span0',
|
||||
},
|
||||
},
|
||||
{
|
||||
refType: 'CHILD_OF',
|
||||
traceID: 'otherTrace',
|
||||
},
|
||||
{
|
||||
refType: 'CHILD_OF',
|
||||
traceID: 'otherTrace',
|
||||
spanID: 'span1',
|
||||
span: {
|
||||
spanID: 'span1',
|
||||
span: {
|
||||
spanID: 'span1',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
props.span
|
||||
);
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const spanRow = shallow(<SpanBarRow {...props} span={span} />)
|
||||
.dive()
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
// limitations under the License.
|
||||
|
||||
import * as React from 'react';
|
||||
|
||||
import IoAlert from 'react-icons/lib/io/alert';
|
||||
import IoArrowRightA from 'react-icons/lib/io/arrow-right-a';
|
||||
import IoNetwork from 'react-icons/lib/io/network';
|
||||
import MdFileUpload from 'react-icons/lib/md/file-upload';
|
||||
import { css, keyframes } from '@emotion/css';
|
||||
import cx from 'classnames';
|
||||
import { stylesFactory, withTheme2 } from '@grafana/ui';
|
||||
import { Icon, stylesFactory, withTheme2 } from '@grafana/ui';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
|
||||
import ReferencesButton from './ReferencesButton';
|
||||
@@ -510,7 +510,7 @@ export class UnthemedSpanBarRow extends React.PureComponent<SpanBarRowProps> {
|
||||
tooltipText="Contains multiple references"
|
||||
focusSpan={focusSpan}
|
||||
>
|
||||
<IoNetwork />
|
||||
<Icon name="link" />
|
||||
</ReferencesButton>
|
||||
)}
|
||||
{span.subsidiarilyReferencedBy && span.subsidiarilyReferencedBy.length > 0 && (
|
||||
|
||||
@@ -104,7 +104,7 @@ describe('<References>', () => {
|
||||
expect(serviceName).toBe(span.process.serviceName);
|
||||
expect(endpointName).toBe(span.operationName);
|
||||
} else {
|
||||
expect(serviceName).toBe('< span in another trace >');
|
||||
expect(serviceName).toBe('View Linked Span ');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,17 +14,51 @@
|
||||
|
||||
import * as React from 'react';
|
||||
import { css } from '@emotion/css';
|
||||
import cx from 'classnames';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
import { Icon, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import AccordianKeyValues from './AccordianKeyValues';
|
||||
import IoIosArrowDown from 'react-icons/lib/io/ios-arrow-down';
|
||||
import IoIosArrowRight from 'react-icons/lib/io/ios-arrow-right';
|
||||
import { TraceSpanReference } from '../../types/trace';
|
||||
import ReferenceLink from '../../url/ReferenceLink';
|
||||
import { uAlignIcon } from '../../uberUtilityStyles';
|
||||
import { uAlignIcon, ubMb1 } from '../../uberUtilityStyles';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { autoColor } from '../../Theme';
|
||||
|
||||
const getStyles = () => {
|
||||
const getStyles = (theme: GrafanaTheme2) => {
|
||||
return {
|
||||
AccordianReferenceItem: css`
|
||||
border-bottom: 1px solid ${autoColor(theme, '#d8d8d8')};
|
||||
`,
|
||||
AccordianKeyValues: css`
|
||||
margin-left: 10px;
|
||||
`,
|
||||
AccordianReferences: css`
|
||||
label: AccordianReferences;
|
||||
border: 1px solid ${autoColor(theme, '#d8d8d8')};
|
||||
position: relative;
|
||||
margin-bottom: 0.25rem;
|
||||
`,
|
||||
AccordianReferencesHeader: css`
|
||||
label: AccordianReferencesHeader;
|
||||
background: ${autoColor(theme, '#e4e4e4')};
|
||||
color: inherit;
|
||||
display: block;
|
||||
padding: 0.25rem 0.5rem;
|
||||
&:hover {
|
||||
background: ${autoColor(theme, '#dadada')};
|
||||
}
|
||||
`,
|
||||
AccordianReferencesContent: css`
|
||||
label: AccordianReferencesContent;
|
||||
background: ${autoColor(theme, '#f0f0f0')};
|
||||
border-top: 1px solid ${autoColor(theme, '#d8d8d8')};
|
||||
padding: 0.5rem 0.5rem 0.25rem 0.5rem;
|
||||
`,
|
||||
AccordianReferencesFooter: css`
|
||||
label: AccordianReferencesFooter;
|
||||
color: ${autoColor(theme, '#999')};
|
||||
`,
|
||||
ReferencesList: css`
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
@@ -53,6 +87,9 @@ const getStyles = () => {
|
||||
debugInfo: css`
|
||||
letter-spacing: 0.25px;
|
||||
margin: 0.5em 0 0;
|
||||
flex-wrap: wrap;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
`,
|
||||
debugLabel: css`
|
||||
margin: 0 5px 0 5px;
|
||||
@@ -69,86 +106,117 @@ type AccordianReferencesProps = {
|
||||
highContrast?: boolean;
|
||||
interactive?: boolean;
|
||||
isOpen: boolean;
|
||||
openedItems?: Set<TraceSpanReference>;
|
||||
onItemToggle?: (reference: TraceSpanReference) => void;
|
||||
onToggle?: null | (() => void);
|
||||
focusSpan: (uiFind: string) => void;
|
||||
};
|
||||
|
||||
type ReferenceItemProps = {
|
||||
data: TraceSpanReference[];
|
||||
interactive?: boolean;
|
||||
openedItems?: Set<TraceSpanReference>;
|
||||
onItemToggle?: (reference: TraceSpanReference) => void;
|
||||
focusSpan: (uiFind: string) => void;
|
||||
};
|
||||
|
||||
// export for test
|
||||
export function References(props: ReferenceItemProps) {
|
||||
const { data, focusSpan } = props;
|
||||
const { data, focusSpan, openedItems, onItemToggle, interactive } = props;
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
return (
|
||||
<div className={cx(styles.ReferencesList)}>
|
||||
<ul className={styles.list}>
|
||||
{data.map((reference) => {
|
||||
return (
|
||||
<li className={styles.item} key={`${reference.spanID}`}>
|
||||
<ReferenceLink reference={reference} focusSpan={focusSpan}>
|
||||
<span className={styles.itemContent}>
|
||||
{reference.span ? (
|
||||
<span>
|
||||
<span className="span-svc-name">{reference.span.process.serviceName}</span>
|
||||
<small className="endpoint-name">{reference.span.operationName}</small>
|
||||
</span>
|
||||
) : (
|
||||
<span className="span-svc-name">< span in another trace ></span>
|
||||
)}
|
||||
<small className={styles.debugInfo}>
|
||||
<span className={styles.debugLabel} data-label="Reference Type:">
|
||||
{reference.refType}
|
||||
</span>
|
||||
<span className={styles.debugLabel} data-label="SpanID:">
|
||||
{reference.spanID}
|
||||
</span>
|
||||
</small>
|
||||
</span>
|
||||
</ReferenceLink>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
<div className={styles.AccordianReferencesContent}>
|
||||
{data.map((reference, i) => (
|
||||
<div className={i < data.length - 1 ? styles.AccordianReferenceItem : undefined} key={reference.spanID}>
|
||||
<div className={styles.item} key={`${reference.spanID}`}>
|
||||
<ReferenceLink reference={reference} focusSpan={focusSpan}>
|
||||
<span className={styles.itemContent}>
|
||||
{reference.span ? (
|
||||
<span>
|
||||
<span className="span-svc-name">{reference.span.process.serviceName}</span>
|
||||
<small className="endpoint-name">{reference.span.operationName}</small>
|
||||
</span>
|
||||
) : (
|
||||
<span className="span-svc-name">
|
||||
View Linked Span <Icon name="external-link-alt" />
|
||||
</span>
|
||||
)}
|
||||
<small className={styles.debugInfo}>
|
||||
<span className={styles.debugLabel} data-label="TraceID:">
|
||||
{reference.traceID}
|
||||
</span>
|
||||
<span className={styles.debugLabel} data-label="SpanID:">
|
||||
{reference.spanID}
|
||||
</span>
|
||||
</small>
|
||||
</span>
|
||||
</ReferenceLink>
|
||||
</div>
|
||||
{!!reference.tags?.length && (
|
||||
<div className={styles.AccordianKeyValues}>
|
||||
<AccordianKeyValues
|
||||
className={i < data.length - 1 ? ubMb1 : null}
|
||||
data={reference.tags || []}
|
||||
highContrast
|
||||
interactive={interactive}
|
||||
isOpen={openedItems ? openedItems.has(reference) : false}
|
||||
label={'attributes'}
|
||||
linksGetter={null}
|
||||
onToggle={interactive && onItemToggle ? () => onItemToggle(reference) : null}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default class AccordianReferences extends React.PureComponent<AccordianReferencesProps> {
|
||||
static defaultProps: Partial<AccordianReferencesProps> = {
|
||||
highContrast: false,
|
||||
interactive: true,
|
||||
onToggle: null,
|
||||
};
|
||||
|
||||
render() {
|
||||
const { data, interactive, isOpen, onToggle, focusSpan } = this.props;
|
||||
const isEmpty = !Array.isArray(data) || !data.length;
|
||||
const iconCls = uAlignIcon;
|
||||
let arrow: React.ReactNode | null = null;
|
||||
let headerProps: {} | null = null;
|
||||
if (interactive) {
|
||||
arrow = isOpen ? <IoIosArrowDown className={iconCls} /> : <IoIosArrowRight className={iconCls} />;
|
||||
headerProps = {
|
||||
'aria-checked': isOpen,
|
||||
onClick: isEmpty ? null : onToggle,
|
||||
role: 'switch',
|
||||
};
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<div {...headerProps}>
|
||||
{arrow}
|
||||
<strong>
|
||||
<span>References</span>
|
||||
</strong>{' '}
|
||||
({data.length})
|
||||
</div>
|
||||
{isOpen && <References data={data} focusSpan={focusSpan} />}
|
||||
</div>
|
||||
);
|
||||
const AccordianReferences: React.FC<AccordianReferencesProps> = ({
|
||||
data,
|
||||
interactive = true,
|
||||
isOpen,
|
||||
onToggle,
|
||||
onItemToggle,
|
||||
openedItems,
|
||||
focusSpan,
|
||||
}) => {
|
||||
const isEmpty = !Array.isArray(data) || !data.length;
|
||||
let arrow: React.ReactNode | null = null;
|
||||
let HeaderComponent: 'span' | 'a' = 'span';
|
||||
let headerProps: {} | null = null;
|
||||
if (interactive) {
|
||||
arrow = isOpen ? <IoIosArrowDown className={uAlignIcon} /> : <IoIosArrowRight className={uAlignIcon} />;
|
||||
HeaderComponent = 'a';
|
||||
headerProps = {
|
||||
'aria-checked': isOpen,
|
||||
onClick: isEmpty ? null : onToggle,
|
||||
role: 'switch',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const styles = useStyles2(getStyles);
|
||||
return (
|
||||
<div className={styles.AccordianReferences}>
|
||||
<HeaderComponent className={styles.AccordianReferencesHeader} {...headerProps}>
|
||||
{arrow}
|
||||
<strong>
|
||||
<span>References</span>
|
||||
</strong>{' '}
|
||||
({data.length})
|
||||
</HeaderComponent>
|
||||
{isOpen && (
|
||||
<References
|
||||
data={data}
|
||||
openedItems={openedItems}
|
||||
focusSpan={focusSpan}
|
||||
onItemToggle={onItemToggle}
|
||||
interactive={interactive}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(AccordianReferences);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { TraceLog } from '../../types/trace';
|
||||
import { TraceLog, TraceSpanReference } from '../../types/trace';
|
||||
|
||||
/**
|
||||
* Which items of a {@link SpanDetail} component are expanded.
|
||||
@@ -21,6 +21,7 @@ export default class DetailState {
|
||||
isTagsOpen: boolean;
|
||||
isProcessOpen: boolean;
|
||||
logs: { isOpen: boolean; openedItems: Set<TraceLog> };
|
||||
references: { isOpen: boolean; openedItems: Set<TraceSpanReference> };
|
||||
isWarningsOpen: boolean;
|
||||
isStackTracesOpen: boolean;
|
||||
isReferencesOpen: boolean;
|
||||
@@ -33,6 +34,7 @@ export default class DetailState {
|
||||
isWarningsOpen,
|
||||
isStackTracesOpen,
|
||||
logs,
|
||||
references,
|
||||
}: DetailState | Record<string, undefined> = oldState || {};
|
||||
this.isTagsOpen = Boolean(isTagsOpen);
|
||||
this.isProcessOpen = Boolean(isProcessOpen);
|
||||
@@ -43,6 +45,10 @@ export default class DetailState {
|
||||
isOpen: Boolean(logs && logs.isOpen),
|
||||
openedItems: logs && logs.openedItems ? new Set(logs.openedItems) : new Set(),
|
||||
};
|
||||
this.references = {
|
||||
isOpen: Boolean(references && references.isOpen),
|
||||
openedItems: references && references.openedItems ? new Set(references.openedItems) : new Set(),
|
||||
};
|
||||
}
|
||||
|
||||
toggleTags() {
|
||||
@@ -59,7 +65,17 @@ export default class DetailState {
|
||||
|
||||
toggleReferences() {
|
||||
const next = new DetailState(this);
|
||||
next.isReferencesOpen = !this.isReferencesOpen;
|
||||
next.references.isOpen = !this.references.isOpen;
|
||||
return next;
|
||||
}
|
||||
|
||||
toggleReferenceItem(reference: TraceSpanReference) {
|
||||
const next = new DetailState(this);
|
||||
if (next.references.openedItems.has(reference)) {
|
||||
next.references.openedItems.delete(reference);
|
||||
} else {
|
||||
next.references.openedItems.add(reference);
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import DetailState from './DetailState';
|
||||
import { formatDuration } from '../utils';
|
||||
import LabeledList from '../../common/LabeledList';
|
||||
import { SpanLinkFunc, TNil } from '../../types';
|
||||
import { TraceKeyValuePair, TraceLink, TraceLog, TraceSpan } from '../../types/trace';
|
||||
import { TraceKeyValuePair, TraceLink, TraceLog, TraceSpan, TraceSpanReference } from '../../types/trace';
|
||||
import AccordianReferences from './AccordianReferences';
|
||||
import { autoColor } from '../../Theme';
|
||||
import { Divider } from '../../common/Divider';
|
||||
@@ -110,6 +110,7 @@ type SpanDetailProps = {
|
||||
traceStartTime: number;
|
||||
warningsToggle: (spanID: string) => void;
|
||||
stackTracesToggle: (spanID: string) => void;
|
||||
referenceItemToggle: (spanID: string, reference: TraceSpanReference) => void;
|
||||
referencesToggle: (spanID: string) => void;
|
||||
focusSpan: (uiFind: string) => void;
|
||||
createSpanLink?: SpanLinkFunc;
|
||||
@@ -130,6 +131,7 @@ export default function SpanDetail(props: SpanDetailProps) {
|
||||
warningsToggle,
|
||||
stackTracesToggle,
|
||||
referencesToggle,
|
||||
referenceItemToggle,
|
||||
focusSpan,
|
||||
createSpanLink,
|
||||
createFocusSpanLink,
|
||||
@@ -139,7 +141,7 @@ export default function SpanDetail(props: SpanDetailProps) {
|
||||
isProcessOpen,
|
||||
logs: logsState,
|
||||
isWarningsOpen,
|
||||
isReferencesOpen,
|
||||
references: referencesState,
|
||||
isStackTracesOpen,
|
||||
} = detailState;
|
||||
const {
|
||||
@@ -258,8 +260,10 @@ export default function SpanDetail(props: SpanDetailProps) {
|
||||
{references && references.length > 0 && (references.length > 1 || references[0].refType !== 'CHILD_OF') && (
|
||||
<AccordianReferences
|
||||
data={references}
|
||||
isOpen={isReferencesOpen}
|
||||
isOpen={referencesState.isOpen}
|
||||
openedItems={referencesState.openedItems}
|
||||
onToggle={() => referencesToggle(spanID)}
|
||||
onItemToggle={(reference) => referenceItemToggle(spanID, reference)}
|
||||
focusSpan={focusSpan}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -23,7 +23,7 @@ import { autoColor } from '../Theme';
|
||||
import { stylesFactory, withTheme2 } from '@grafana/ui';
|
||||
import { GrafanaTheme2, LinkModel } from '@grafana/data';
|
||||
|
||||
import { TraceLog, TraceSpan, TraceKeyValuePair, TraceLink } from '../types/trace';
|
||||
import { TraceLog, TraceSpan, TraceKeyValuePair, TraceLink, TraceSpanReference } from '../types/trace';
|
||||
import { SpanLinkFunc } from '../types';
|
||||
|
||||
const getStyles = stylesFactory((theme: GrafanaTheme2) => {
|
||||
@@ -77,6 +77,7 @@ type SpanDetailRowProps = {
|
||||
logItemToggle: (spanID: string, log: TraceLog) => void;
|
||||
logsToggle: (spanID: string) => void;
|
||||
processToggle: (spanID: string) => void;
|
||||
referenceItemToggle: (spanID: string, reference: TraceSpanReference) => void;
|
||||
referencesToggle: (spanID: string) => void;
|
||||
warningsToggle: (spanID: string) => void;
|
||||
stackTracesToggle: (spanID: string) => void;
|
||||
@@ -111,6 +112,7 @@ export class UnthemedSpanDetailRow extends React.PureComponent<SpanDetailRowProp
|
||||
logItemToggle,
|
||||
logsToggle,
|
||||
processToggle,
|
||||
referenceItemToggle,
|
||||
referencesToggle,
|
||||
warningsToggle,
|
||||
stackTracesToggle,
|
||||
@@ -156,6 +158,7 @@ export class UnthemedSpanDetailRow extends React.PureComponent<SpanDetailRowProp
|
||||
logItemToggle={logItemToggle}
|
||||
logsToggle={logsToggle}
|
||||
processToggle={processToggle}
|
||||
referenceItemToggle={referenceItemToggle}
|
||||
referencesToggle={referencesToggle}
|
||||
warningsToggle={warningsToggle}
|
||||
stackTracesToggle={stackTracesToggle}
|
||||
|
||||
@@ -35,7 +35,7 @@ import {
|
||||
import { Accessors } from '../ScrollManager';
|
||||
import { getColorByKey } from '../utils/color-generator';
|
||||
import { SpanLinkFunc, TNil } from '../types';
|
||||
import { TraceLog, TraceSpan, Trace, TraceKeyValuePair, TraceLink } from '../types/trace';
|
||||
import { TraceLog, TraceSpan, Trace, TraceKeyValuePair, TraceLink, TraceSpanReference } from '../types/trace';
|
||||
import TTraceTimeline from '../types/TTraceTimeline';
|
||||
import { PEER_SERVICE } from '../constants/tag-keys';
|
||||
|
||||
@@ -75,6 +75,7 @@ type TVirtualizedTraceViewOwnProps = {
|
||||
detailWarningsToggle: (spanID: string) => void;
|
||||
detailStackTracesToggle: (spanID: string) => void;
|
||||
detailReferencesToggle: (spanID: string) => void;
|
||||
detailReferenceItemToggle: (spanID: string, reference: TraceSpanReference) => void;
|
||||
detailProcessToggle: (spanID: string) => void;
|
||||
detailTagsToggle: (spanID: string) => void;
|
||||
detailToggle: (spanID: string) => void;
|
||||
@@ -440,6 +441,7 @@ export class UnthemedVirtualizedTraceView extends React.Component<VirtualizedTra
|
||||
detailLogsToggle,
|
||||
detailProcessToggle,
|
||||
detailReferencesToggle,
|
||||
detailReferenceItemToggle,
|
||||
detailWarningsToggle,
|
||||
detailStackTracesToggle,
|
||||
detailStates,
|
||||
@@ -474,6 +476,7 @@ export class UnthemedVirtualizedTraceView extends React.Component<VirtualizedTra
|
||||
logItemToggle={detailLogItemToggle}
|
||||
logsToggle={detailLogsToggle}
|
||||
processToggle={detailProcessToggle}
|
||||
referenceItemToggle={detailReferenceItemToggle}
|
||||
referencesToggle={detailReferencesToggle}
|
||||
warningsToggle={detailWarningsToggle}
|
||||
stackTracesToggle={detailStackTracesToggle}
|
||||
|
||||
@@ -23,7 +23,7 @@ import { merge as mergeShortcuts } from '../keyboard-shortcuts';
|
||||
import { Accessors } from '../ScrollManager';
|
||||
import { TUpdateViewRangeTimeFunction, ViewRange, ViewRangeTimeUpdate } from './types';
|
||||
import { SpanLinkFunc, TNil } from '../types';
|
||||
import { TraceSpan, Trace, TraceLog, TraceKeyValuePair, TraceLink } from '../types/trace';
|
||||
import { TraceSpan, Trace, TraceLog, TraceKeyValuePair, TraceLink, TraceSpanReference } from '../types/trace';
|
||||
import TTraceTimeline from '../types/TTraceTimeline';
|
||||
import { autoColor } from '../Theme';
|
||||
import ExternalLinkContext from '../url/externalLinkContext';
|
||||
@@ -93,6 +93,7 @@ type TProps = TExtractUiFindFromStateReturn & {
|
||||
detailWarningsToggle: (spanID: string) => void;
|
||||
detailStackTracesToggle: (spanID: string) => void;
|
||||
detailReferencesToggle: (spanID: string) => void;
|
||||
detailReferenceItemToggle: (spanID: string, reference: TraceSpanReference) => void;
|
||||
detailProcessToggle: (spanID: string) => void;
|
||||
detailTagsToggle: (spanID: string) => void;
|
||||
detailToggle: (spanID: string) => void;
|
||||
|
||||
@@ -44,6 +44,7 @@ export type TraceSpanReference = {
|
||||
span?: TraceSpan | null | undefined;
|
||||
spanID: string;
|
||||
traceID: string;
|
||||
tags?: TraceKeyValuePair[];
|
||||
};
|
||||
|
||||
export type TraceSpanData = {
|
||||
|
||||
@@ -41,6 +41,7 @@ export default function ReferenceLink(props: ReferenceLinkProps) {
|
||||
if (!createLinkToExternalSpan) {
|
||||
throw new Error("ExternalLinkContext does not have a value, you probably forgot to setup it's provider");
|
||||
}
|
||||
|
||||
return (
|
||||
<a
|
||||
href={createLinkToExternalSpan(reference.traceID, reference.spanID)}
|
||||
|
||||
Reference in New Issue
Block a user