import {useMemo} from 'react'; import styled from '@emotion/styled'; import * as Sentry from '@sentry/react'; import NoProjectMessage from 'sentry/components/noProjectMessage'; import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle'; import {t} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import useOrganization from 'sentry/utils/useOrganization'; import {useParams} from 'sentry/utils/useParams'; import {TraceWaterfall} from 'sentry/views/performance/newTraceDetails/traceWaterfall'; import {useTrace} from './traceApi/useTrace'; import {useTraceMeta} from './traceApi/useTraceMeta'; import {useTraceRootEvent} from './traceApi/useTraceRootEvent'; import {useTraceTree} from './traceApi/useTraceTree'; import { DEFAULT_TRACE_VIEW_PREFERENCES, loadTraceViewPreferences, } from './traceState/tracePreferences'; import {TraceStateProvider} from './traceState/traceStateProvider'; import {TraceMetaDataHeader} from './traceHeader'; import {useTraceEventView} from './useTraceEventView'; import {useTraceQueryParams} from './useTraceQueryParams'; function decodeTraceSlug(maybeSlug: string | undefined): string { if (!maybeSlug || maybeSlug === 'null' || maybeSlug === 'undefined') { Sentry.withScope(scope => { scope.setFingerprint(['trace-null-slug']); Sentry.captureMessage(`Trace slug is empty`); }); return ''; } return maybeSlug.trim(); } export function TraceView() { const organization = useOrganization(); const params = useParams<{traceSlug?: string}>(); const traceSlug = useMemo(() => decodeTraceSlug(params.traceSlug), [params.traceSlug]); const queryParams = useTraceQueryParams(); const traceEventView = useTraceEventView(traceSlug, queryParams); const preferences = useMemo( () => loadTraceViewPreferences('trace-view-preferences') || DEFAULT_TRACE_VIEW_PREFERENCES, [] ); const meta = useTraceMeta([{traceSlug, timestamp: queryParams.timestamp}]); const trace = useTrace({traceSlug, timestamp: queryParams.timestamp}); const rootEvent = useTraceRootEvent(trace.data ?? null); const tree = useTraceTree({traceSlug, trace, meta, replay: null}); return ( ); } const TraceExternalLayout = styled('div')` display: flex; flex-direction: column; flex: 1 1 100%; ~ footer { display: none; } `; const TraceInnerLayout = styled('div')` display: flex; flex-direction: column; flex: 1 1 100%; padding: ${space(2)}; background-color: ${p => p.theme.background}; `;