123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- import {Location} from 'history';
- import Feature from 'sentry/components/acl/feature';
- import FeatureDisabled from 'sentry/components/acl/featureDisabled';
- import ErrorBoundary from 'sentry/components/errorBoundary';
- import {Hovercard} from 'sentry/components/hovercard';
- import ExternalLink from 'sentry/components/links/externalLink';
- import Link from 'sentry/components/links/link';
- import Placeholder from 'sentry/components/placeholder';
- import QuickTrace from 'sentry/components/quickTrace';
- import {generateTraceTarget} from 'sentry/components/quickTrace/utils';
- import {t, tct, tn} from 'sentry/locale';
- import {AvatarProject, OrganizationSummary} from 'sentry/types';
- import {Event} from 'sentry/types/event';
- import {trackAnalytics} from 'sentry/utils/analytics';
- import {getConfigureTracingDocsLink} from 'sentry/utils/docs';
- import {getShortEventId} from 'sentry/utils/events';
- import {
- QuickTraceQueryChildrenProps,
- TraceMeta,
- } from 'sentry/utils/performance/quickTrace/types';
- import useOrganization from 'sentry/utils/useOrganization';
- import {MetaData} from './styles';
- type Props = Pick<
- React.ComponentProps<typeof QuickTrace>,
- 'errorDest' | 'transactionDest'
- > & {
- anchor: 'left' | 'right';
- event: Event;
- location: Location;
- quickTrace: QuickTraceQueryChildrenProps | null;
- traceMeta: TraceMeta | null;
- project?: AvatarProject;
- };
- function handleTraceLink(organization: OrganizationSummary) {
- trackAnalytics('quick_trace.trace_id.clicked', {
- organization: organization.id,
- source: 'events',
- });
- }
- export default function QuickTraceMeta({
- event,
- location,
- quickTrace,
- traceMeta,
- anchor,
- errorDest,
- transactionDest,
- project,
- }: Props) {
- const organization = useOrganization();
- const features = ['performance-view'];
- const noFeatureMessage = t('Requires performance monitoring.');
- const docsLink = getConfigureTracingDocsLink(project);
- const traceId = event.contexts?.trace?.trace_id ?? null;
- const traceTarget = generateTraceTarget(event, organization);
- let body: React.ReactNode;
- let footer: React.ReactNode;
- if (!traceId || !quickTrace || quickTrace.trace === null) {
- // this platform doesn't support performance don't show anything here
- if (docsLink === null) {
- return null;
- }
- body = t('Missing Trace');
- // need to configure tracing
- footer = <ExternalLink href={docsLink}>{t('Read the docs')}</ExternalLink>;
- } else {
- if (quickTrace.isLoading) {
- body = <Placeholder height="20px" />;
- } else if (quickTrace.error) {
- body = '\u2014';
- } else {
- body = (
- <ErrorBoundary mini>
- <QuickTrace
- event={event}
- quickTrace={{
- type: quickTrace.type,
- trace: quickTrace.trace,
- }}
- location={location}
- organization={organization}
- anchor={anchor}
- errorDest={errorDest}
- transactionDest={transactionDest}
- />
- </ErrorBoundary>
- );
- }
- footer = (
- <Link to={traceTarget} onClick={() => handleTraceLink(organization)}>
- {tct('View Full Trace: [id][events]', {
- id: getShortEventId(traceId ?? ''),
- events: traceMeta
- ? tn(' (%s event)', ' (%s events)', traceMeta.transactions + traceMeta.errors)
- : '',
- })}
- </Link>
- );
- }
- return (
- <Feature hookName="feature-disabled:performance-quick-trace" features={features}>
- {({hasFeature}) => {
- // also need to enable the performance feature
- if (!hasFeature) {
- footer = (
- <Hovercard
- body={
- <FeatureDisabled
- features={features}
- hideHelpToggle
- message={noFeatureMessage}
- featureName={noFeatureMessage}
- />
- }
- >
- {footer}
- </Hovercard>
- );
- }
- return <QuickTraceMetaBase body={body} footer={footer} />;
- }}
- </Feature>
- );
- }
- export function QuickTraceMetaBase({
- body,
- footer,
- }: {
- body: React.ReactNode;
- footer: React.ReactNode;
- }) {
- return (
- <MetaData
- headingText={t('Trace Navigator')}
- tooltipText={t(
- 'An abbreviated version of the full trace. Related frontend and backend services can be added to provide further visibility.'
- )}
- bodyText={<div data-test-id="quick-trace-body">{body}</div>}
- subtext={<div data-test-id="quick-trace-footer">{footer}</div>}
- />
- );
- }
|