index.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import {useMemo} from 'react';
  2. import styled from '@emotion/styled';
  3. import * as Sentry from '@sentry/react';
  4. import NoProjectMessage from 'sentry/components/noProjectMessage';
  5. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  6. import {t} from 'sentry/locale';
  7. import {space} from 'sentry/styles/space';
  8. import useOrganization from 'sentry/utils/useOrganization';
  9. import {useParams} from 'sentry/utils/useParams';
  10. import {TraceContextPanel} from 'sentry/views/performance/newTraceDetails/traceContextPanel';
  11. import {TraceWaterfall} from 'sentry/views/performance/newTraceDetails/traceWaterfall';
  12. import {useHasTraceNewUi} from 'sentry/views/performance/newTraceDetails/useHasTraceNewUi';
  13. import {useTrace} from './traceApi/useTrace';
  14. import {useTraceMeta} from './traceApi/useTraceMeta';
  15. import {useTraceRootEvent} from './traceApi/useTraceRootEvent';
  16. import {useTraceTree} from './traceApi/useTraceTree';
  17. import {
  18. DEFAULT_TRACE_VIEW_PREFERENCES,
  19. loadTraceViewPreferences,
  20. } from './traceState/tracePreferences';
  21. import {TraceStateProvider} from './traceState/traceStateProvider';
  22. import {TraceMetaDataHeader} from './traceHeader';
  23. import {useTraceEventView} from './useTraceEventView';
  24. import {useTraceQueryParams} from './useTraceQueryParams';
  25. function decodeTraceSlug(maybeSlug: string | undefined): string {
  26. if (!maybeSlug || maybeSlug === 'null' || maybeSlug === 'undefined') {
  27. Sentry.withScope(scope => {
  28. scope.setFingerprint(['trace-null-slug']);
  29. Sentry.captureMessage(`Trace slug is empty`);
  30. });
  31. return '';
  32. }
  33. return maybeSlug.trim();
  34. }
  35. export function TraceView() {
  36. const organization = useOrganization();
  37. const params = useParams<{traceSlug?: string}>();
  38. const traceSlug = useMemo(() => decodeTraceSlug(params.traceSlug), [params.traceSlug]);
  39. const queryParams = useTraceQueryParams();
  40. const traceEventView = useTraceEventView(traceSlug, queryParams);
  41. const hasTraceNewUi = useHasTraceNewUi();
  42. const preferences = useMemo(
  43. () =>
  44. loadTraceViewPreferences('trace-view-preferences') ||
  45. DEFAULT_TRACE_VIEW_PREFERENCES,
  46. []
  47. );
  48. const meta = useTraceMeta([{traceSlug, timestamp: queryParams.timestamp}]);
  49. const trace = useTrace({traceSlug, timestamp: queryParams.timestamp});
  50. const rootEvent = useTraceRootEvent(trace.data ?? null);
  51. const tree = useTraceTree({traceSlug, trace, meta, replay: null});
  52. return (
  53. <SentryDocumentTitle
  54. title={`${t('Trace Details')} - ${traceSlug}`}
  55. orgSlug={organization.slug}
  56. >
  57. <TraceStateProvider
  58. initialPreferences={preferences}
  59. preferencesStorageKey="trace-view-preferences"
  60. >
  61. <NoProjectMessage organization={organization}>
  62. <TraceExternalLayout>
  63. <TraceMetaDataHeader
  64. rootEventResults={rootEvent}
  65. tree={tree}
  66. metaResults={meta}
  67. organization={organization}
  68. traceSlug={traceSlug}
  69. traceEventView={traceEventView}
  70. />
  71. <TraceInnerLayout>
  72. <TraceWaterfall
  73. tree={tree}
  74. trace={trace}
  75. meta={meta}
  76. replay={null}
  77. source="performance"
  78. rootEvent={rootEvent}
  79. traceSlug={traceSlug}
  80. traceEventView={traceEventView}
  81. organization={organization}
  82. />
  83. {hasTraceNewUi && <TraceContextPanel tree={tree} rootEvent={rootEvent} />}
  84. </TraceInnerLayout>
  85. </TraceExternalLayout>
  86. </NoProjectMessage>
  87. </TraceStateProvider>
  88. </SentryDocumentTitle>
  89. );
  90. }
  91. const TraceExternalLayout = styled('div')`
  92. display: flex;
  93. flex-direction: column;
  94. flex: 1 1 100%;
  95. ~ footer {
  96. display: none;
  97. }
  98. `;
  99. const TraceInnerLayout = styled('div')`
  100. display: flex;
  101. flex-direction: column;
  102. flex: 1 1 100%;
  103. padding: ${space(2)};
  104. background-color: ${p => p.theme.surface100};
  105. `;