Browse Source

feat(issue-details): Add 'View Full Trace' to right of trace navigator (#46630)

Closes https://github.com/getsentry/sentry/issues/46560

Removes "View Full Trace" from the overflow menu and adds it as a link
to the right of the trace navigator.
Malachi Willey 1 year ago
parent
commit
bb35f9ec1d

+ 0 - 24
static/app/views/issueDetails/groupEventCarousel.tsx

@@ -1,4 +1,3 @@
-import {useContext} from 'react';
 import {useTheme} from '@emotion/react';
 import styled from '@emotion/styled';
 import moment from 'moment-timezone';
@@ -8,7 +7,6 @@ import {Button} from 'sentry/components/button';
 import ButtonBar from 'sentry/components/buttonBar';
 import Clipboard from 'sentry/components/clipboard';
 import {DropdownMenu} from 'sentry/components/dropdownMenu';
-import {generateTraceTarget} from 'sentry/components/quickTrace/utils';
 import TimeSince from 'sentry/components/timeSince';
 import {Tooltip} from 'sentry/components/tooltip';
 import {
@@ -24,7 +22,6 @@ import {t} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
 import {Event, Group} from 'sentry/types';
 import {defined, formatBytesBase2} from 'sentry/utils';
-import {trackAnalyticsEvent} from 'sentry/utils/analytics';
 import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent';
 import {eventDetailsRoute, generateEventSlug} from 'sentry/utils/discover/urls';
 import {
@@ -33,7 +30,6 @@ import {
   getShortEventId,
 } from 'sentry/utils/events';
 import getDynamicText from 'sentry/utils/getDynamicText';
-import {QuickTraceContext} from 'sentry/utils/performance/quickTrace/quickTraceContext';
 import {useLocation} from 'sentry/utils/useLocation';
 import useMedia from 'sentry/utils/useMedia';
 import useOrganization from 'sentry/utils/useOrganization';
@@ -103,8 +99,6 @@ export const GroupEventCarousel = ({
     });
   };
 
-  const quickTrace = useContext(QuickTraceContext);
-
   return (
     <CarouselAndButtonsWrapper>
       <StyledButtonBar merged>
@@ -239,24 +233,6 @@ export const GroupEventCarousel = ({
               });
             },
           },
-          {
-            key: 'full-trace',
-            label: t('View Full Trace'),
-            hidden:
-              !defined(quickTrace) ||
-              defined(quickTrace.error) ||
-              quickTrace.isLoading ||
-              quickTrace.type === 'empty',
-            to: generateTraceTarget(event, organization),
-            onAction: () => {
-              trackAnalyticsEvent({
-                eventKey: 'quick_trace.trace_id.clicked',
-                eventName: 'Quick Trace: Trace ID clicked',
-                organization_id: parseInt(organization.id, 10),
-                source: 'issues',
-              });
-            },
-          },
           {
             key: 'replay',
             label: t('View Replay'),

+ 38 - 24
static/app/views/issueDetails/quickTrace/issueQuickTrace.tsx

@@ -21,6 +21,7 @@ import {defined} from 'sentry/utils';
 import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent';
 import {QuickTraceQueryChildrenProps} from 'sentry/utils/performance/quickTrace/types';
 import useOrganization from 'sentry/utils/useOrganization';
+import {TraceLink} from 'sentry/views/issueDetails/quickTrace/traceLink';
 
 type Props = {
   event: Event;
@@ -32,8 +33,10 @@ type Props = {
 
 function TransactionMissingPlaceholder({
   type,
+  event,
   group,
 }: {
+  event: Event;
   group: Group;
   type?: QuickTraceQueryChildrenProps['type'];
 }) {
@@ -48,32 +51,33 @@ function TransactionMissingPlaceholder({
 
   return (
     <QuickTraceWrapper>
-      <Tooltip
-        isHoverable
-        position="bottom"
-        title={tct(
-          'The [type] for this event cannot be found. [link:Read the  docs] to understand why.',
-          {
-            type: type === 'missing' ? t('transaction') : t('trace'),
-            link: (
-              <ExternalLink href="https://docs.sentry.io/product/sentry-basics/tracing/trace-view/#troubleshooting" />
-            ),
-          }
-        )}
-      >
-        <QuickTraceContainer data-test-id="missing-trace-placeholder">
+      <QuickTraceContainer data-test-id="missing-trace-placeholder">
+        <Tooltip
+          isHoverable
+          position="bottom"
+          title={tct(
+            'The [type] for this event cannot be found. [link:Read the  docs] to understand why.',
+            {
+              type: type === 'missing' ? t('transaction') : t('trace'),
+              link: (
+                <ExternalLink href="https://docs.sentry.io/product/sentry-basics/tracing/trace-view/#troubleshooting" />
+              ),
+            }
+          )}
+        >
           <EventNode type="white" icon={null}>
             ???
           </EventNode>
-          <TraceConnector />
-          <EventNode type="error" data-test-id="event-node">
-            <ErrorNodeContent>
-              <IconFire size="xs" />
-              {t('This Event')}
-            </ErrorNodeContent>
-          </EventNode>
-        </QuickTraceContainer>
-      </Tooltip>
+        </Tooltip>
+        <TraceConnector />
+        <EventNode type="error" data-test-id="event-node">
+          <ErrorNodeContent>
+            <IconFire size="xs" />
+            {t('This Event')}
+          </ErrorNodeContent>
+        </EventNode>
+        <TraceLink event={event} />
+      </QuickTraceContainer>
     </QuickTraceWrapper>
   );
 }
@@ -85,7 +89,13 @@ function IssueQuickTrace({group, event, location, organization, quickTrace}: Pro
     !defined(quickTrace.trace) ||
     quickTrace.trace.length === 0
   ) {
-    return <TransactionMissingPlaceholder group={group} type={quickTrace?.type} />;
+    return (
+      <TransactionMissingPlaceholder
+        event={event}
+        group={group}
+        type={quickTrace?.type}
+      />
+    );
   }
 
   trackAdvancedAnalyticsEvent('issue.quick_trace_status', {
@@ -106,12 +116,16 @@ function IssueQuickTrace({group, event, location, organization, quickTrace}: Pro
           errorDest="issue"
           transactionDest="performance"
         />
+        <TraceLink event={event} />
       </QuickTraceWrapper>
     </ErrorBoundary>
   );
 }
 
 const QuickTraceWrapper = styled('div')`
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
   margin-top: ${space(0.5)};
 `;
 

+ 46 - 0
static/app/views/issueDetails/quickTrace/traceLink.tsx

@@ -0,0 +1,46 @@
+import {useCallback, useContext} from 'react';
+import styled from '@emotion/styled';
+
+import Link from 'sentry/components/links/link';
+import {generateTraceTarget} from 'sentry/components/quickTrace/utils';
+import {t} from 'sentry/locale';
+import {space} from 'sentry/styles/space';
+import {Event} from 'sentry/types';
+import {trackAnalyticsEvent} from 'sentry/utils/analytics';
+import {QuickTraceContext} from 'sentry/utils/performance/quickTrace/quickTraceContext';
+import useOrganization from 'sentry/utils/useOrganization';
+
+type TraceLinkProps = {
+  event: Event;
+};
+
+export function TraceLink({event}: TraceLinkProps) {
+  const organization = useOrganization();
+  const quickTrace = useContext(QuickTraceContext);
+  const handleTraceLink = useCallback(() => {
+    trackAnalyticsEvent({
+      eventKey: 'quick_trace.trace_id.clicked',
+      eventName: 'Quick Trace: Trace ID clicked',
+      organization_id: parseInt(organization.id, 10),
+      source: 'issues',
+    });
+  }, [organization.id]);
+
+  if (
+    !quickTrace ||
+    quickTrace.isLoading ||
+    quickTrace.error ||
+    quickTrace.type === 'empty'
+  ) {
+    return null;
+  }
+  return (
+    <StyledLink to={generateTraceTarget(event, organization)} onClick={handleTraceLink}>
+      {t('View Full Trace')}
+    </StyledLink>
+  );
+}
+
+const StyledLink = styled(Link)`
+  margin-left: ${space(1)};
+`;