Просмотр исходного кода

ref(replays): move browser/OS icons and replace with dead/rage count (#57315)

<img width="1174" alt="SCR-20231002-msff"
src="https://github.com/getsentry/sentry/assets/56095982/953670db-b2ff-4679-b3b5-baf556604f95">

Closes https://github.com/getsentry/sentry/issues/57270
Relates to https://github.com/getsentry/sentry/issues/57271
Michelle Zhang 1 год назад
Родитель
Сommit
500262dfe1

+ 31 - 19
static/app/components/replays/header/replayMetaData.tsx

@@ -1,14 +1,13 @@
 import {Fragment} from 'react';
 import styled from '@emotion/styled';
 
-import ContextIcon from 'sentry/components/replays/contextIcon';
 import ErrorCounts from 'sentry/components/replays/header/errorCounts';
 import HeaderPlaceholder from 'sentry/components/replays/header/headerPlaceholder';
 import TimeSince from 'sentry/components/timeSince';
-import {Tooltip} from 'sentry/components/tooltip';
-import {IconCalendar} from 'sentry/icons';
+import {IconCalendar, IconCursorArrow} from 'sentry/icons';
 import {t} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
+import {ColorOrAlias} from 'sentry/utils/theme';
 import type {ReplayError, ReplayRecord} from 'sentry/views/replays/types';
 
 type Props = {
@@ -19,26 +18,28 @@ type Props = {
 function ReplayMetaData({replayErrors, replayRecord}: Props) {
   return (
     <KeyMetrics>
-      <KeyMetricLabel>{t('OS')}</KeyMetricLabel>
+      <KeyMetricLabel>{t('Dead Clicks')}</KeyMetricLabel>
       <KeyMetricData>
-        <Tooltip title={`${replayRecord?.os.name} ${replayRecord?.os.version}`}>
-          <ContextIcon
-            name={replayRecord?.os.name ?? ''}
-            version={replayRecord?.os.version ?? undefined}
-            showVersion
-          />
-        </Tooltip>
+        {replayRecord?.count_dead_clicks ? (
+          <ClickCount color="yellow300">
+            <IconCursorArrow size="sm" />
+            {replayRecord.count_dead_clicks}
+          </ClickCount>
+        ) : (
+          <Count>0</Count>
+        )}
       </KeyMetricData>
 
-      <KeyMetricLabel>{t('Browser')}</KeyMetricLabel>
+      <KeyMetricLabel>{t('Rage Clicks')}</KeyMetricLabel>
       <KeyMetricData>
-        <Tooltip title={`${replayRecord?.browser.name} ${replayRecord?.browser.version}`}>
-          <ContextIcon
-            name={replayRecord?.browser.name ?? ''}
-            version={replayRecord?.browser.version ?? undefined}
-            showVersion
-          />
-        </Tooltip>
+        {replayRecord?.count_rage_clicks ? (
+          <ClickCount color="red300">
+            <IconCursorArrow size="sm" />
+            {replayRecord.count_rage_clicks}
+          </ClickCount>
+        ) : (
+          <Count>0</Count>
+        )}
       </KeyMetricData>
 
       <KeyMetricLabel>{t('Start Time')}</KeyMetricLabel>
@@ -93,4 +94,15 @@ const KeyMetricData = styled('dd')`
   line-height: ${p => p.theme.text.lineHeightBody};
 `;
 
+const Count = styled('span')`
+  font-variant-numeric: tabular-nums;
+`;
+
+const ClickCount = styled(Count)<{color: ColorOrAlias}>`
+  color: ${p => p.theme[p.color]};
+  display: flex;
+  gap: ${space(0.75)};
+  align-items: center;
+`;
+
 export default ReplayMetaData;

+ 14 - 1
static/app/components/replays/replayView.tsx

@@ -4,6 +4,8 @@ import styled from '@emotion/styled';
 import ReplayController from 'sentry/components/replays/replayController';
 import ReplayCurrentUrl from 'sentry/components/replays/replayCurrentUrl';
 import ReplayPlayer from 'sentry/components/replays/replayPlayer';
+import {space} from 'sentry/styles/space';
+import BrowserOSIcons from 'sentry/views/replays/detail/browserOSIcons';
 import FluidHeight from 'sentry/views/replays/detail/layout/fluidHeight';
 
 type Props = {
@@ -13,7 +15,10 @@ type Props = {
 function ReplayView({toggleFullscreen}: Props) {
   return (
     <Fragment>
-      <ReplayCurrentUrl />
+      <ContextContainer>
+        <ReplayCurrentUrl />
+        <BrowserOSIcons />
+      </ContextContainer>
       <Panel>
         <ReplayPlayer />
       </Panel>
@@ -29,4 +34,12 @@ const Panel = styled(FluidHeight)`
   box-shadow: ${p => p.theme.dropShadowMedium};
 `;
 
+const ContextContainer = styled('div')`
+  display: grid;
+  grid-auto-flow: column;
+  grid-template-columns: 1fr max-content max-content;
+  align-items: center;
+  gap: ${space(1)};
+`;
+
 export default ReplayView;

+ 29 - 0
static/app/views/replays/detail/browserOSIcons.tsx

@@ -0,0 +1,29 @@
+import {Fragment} from 'react';
+
+import ContextIcon from 'sentry/components/replays/contextIcon';
+import {useReplayContext} from 'sentry/components/replays/replayContext';
+import {Tooltip} from 'sentry/components/tooltip';
+
+export default function BrowserOSIcons() {
+  const {replay} = useReplayContext();
+  const replayRecord = replay?.getReplay();
+
+  return (
+    <Fragment>
+      <Tooltip title={`${replayRecord?.os.name} ${replayRecord?.os.version}`}>
+        <ContextIcon
+          name={replayRecord?.os.name ?? ''}
+          version={replayRecord?.os.version ?? undefined}
+          showVersion
+        />
+      </Tooltip>
+      <Tooltip title={`${replayRecord?.browser.name} ${replayRecord?.browser.version}`}>
+        <ContextIcon
+          name={replayRecord?.browser.name ?? ''}
+          version={replayRecord?.browser.version ?? undefined}
+          showVersion
+        />
+      </Tooltip>
+    </Fragment>
+  );
+}