Browse Source

feat(replay): Add beta badge for mobile replays (#73302)

In replay list page if all mobile projects:
<img width="1066" alt="image"
src="https://github.com/getsentry/sentry/assets/55311782/878017e3-c038-4ff0-8263-d56eb21dd00d">
In replay details page if mobile replay:
<img width="969" alt="image"
src="https://github.com/getsentry/sentry/assets/55311782/1ef98392-926b-4611-8dcd-2a601786f237">

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

---------

Co-authored-by: Michelle Zhang <56095982+michellewzhang@users.noreply.github.com>
Co-authored-by: getsantry[bot] <66042841+getsantry[bot]@users.noreply.github.com>
Catherine Lee 8 months ago
parent
commit
61c873ca1a

+ 26 - 2
static/app/components/replays/header/detailsPageBreadcrumbs.tsx

@@ -1,9 +1,12 @@
 import {Fragment} from 'react';
+import styled from '@emotion/styled';
 
+import FeatureBadge from 'sentry/components/badge/featureBadge';
 import {Breadcrumbs} from 'sentry/components/breadcrumbs';
 import ProjectBadge from 'sentry/components/idBadge/projectBadge';
 import Placeholder from 'sentry/components/placeholder';
 import {t} from 'sentry/locale';
+import {space} from 'sentry/styles/space';
 import EventView from 'sentry/utils/discover/eventView';
 import {getShortEventId} from 'sentry/utils/events';
 import {useLocation} from 'sentry/utils/useLocation';
@@ -12,11 +15,12 @@ import {normalizeUrl} from 'sentry/utils/withDomainRequired';
 import type {ReplayRecord} from 'sentry/views/replays/types';
 
 type Props = {
+  isVideoReplay: boolean | undefined;
   orgSlug: string;
   replayRecord: ReplayRecord | undefined;
 };
 
-function DetailsPageBreadcrumbs({orgSlug, replayRecord}: Props) {
+function DetailsPageBreadcrumbs({orgSlug, replayRecord, isVideoReplay}: Props) {
   const location = useLocation();
   const eventView = EventView.fromLocation(location);
 
@@ -52,7 +56,19 @@ function DetailsPageBreadcrumbs({orgSlug, replayRecord}: Props) {
           ) : null,
         },
         {
-          label: labelTitle,
+          label: isVideoReplay ? (
+            <StyledSpan>
+              {labelTitle}
+              <CenteredFeatureBadge
+                type="beta"
+                title={t(
+                  'Session Replay for mobile apps is currently in beta. Beta features are still in progress and may have bugs.'
+                )}
+              />
+            </StyledSpan>
+          ) : (
+            labelTitle
+          ),
         },
       ]}
     />
@@ -60,3 +76,11 @@ function DetailsPageBreadcrumbs({orgSlug, replayRecord}: Props) {
 }
 
 export default DetailsPageBreadcrumbs;
+
+const CenteredFeatureBadge = styled(FeatureBadge)`
+  height: ${space(2)};
+`;
+
+const StyledSpan = styled('span')`
+  display: flex;
+`;

+ 10 - 2
static/app/views/replays/detail/page.tsx

@@ -75,11 +75,19 @@ export default function Page({
 
   const header = replayRecord?.is_archived ? (
     <Header>
-      <DetailsPageBreadcrumbs orgSlug={orgSlug} replayRecord={replayRecord} />
+      <DetailsPageBreadcrumbs
+        orgSlug={orgSlug}
+        replayRecord={replayRecord}
+        isVideoReplay={isVideoReplay}
+      />
     </Header>
   ) : (
     <Header>
-      <DetailsPageBreadcrumbs orgSlug={orgSlug} replayRecord={replayRecord} />
+      <DetailsPageBreadcrumbs
+        orgSlug={orgSlug}
+        replayRecord={replayRecord}
+        isVideoReplay={isVideoReplay}
+      />
 
       <ButtonActionsWrapper>
         {isLoading ? (

+ 11 - 0
static/app/views/replays/list.tsx

@@ -1,6 +1,7 @@
 import {Fragment} from 'react';
 import styled from '@emotion/styled';
 
+import FeatureBadge from 'sentry/components/badge/featureBadge';
 import HookOrDefault from 'sentry/components/hookOrDefault';
 import * as Layout from 'sentry/components/layouts/thirds';
 import PageFiltersContainer from 'sentry/components/organizations/pageFilters/container';
@@ -10,6 +11,7 @@ import {t} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
 import useReplayPageview from 'sentry/utils/replays/hooks/useReplayPageview';
 import useOrganization from 'sentry/utils/useOrganization';
+import useAllMobileProj from 'sentry/views/replays/detail/useAllMobileProj';
 import ListContent from 'sentry/views/replays/list/listContent';
 import ReplayTabs from 'sentry/views/replays/tabs';
 
@@ -21,6 +23,7 @@ const ReplayListPageHeaderHook = HookOrDefault({
 function ReplaysListContainer() {
   useReplayPageview('replay.list-time-spent');
   const organization = useOrganization();
+  const {allMobileProj} = useAllMobileProj();
 
   return (
     <SentryDocumentTitle title={`Session Replay — ${organization.slug}`}>
@@ -34,6 +37,14 @@ function ReplaysListContainer() {
               )}
               docsUrl="https://docs.sentry.io/product/session-replay/"
             />
+            {allMobileProj ? (
+              <FeatureBadge
+                type="beta"
+                title={t(
+                  'Session Replay for mobile apps is currently in beta. Beta features are still in progress and may have bugs.'
+                )}
+              />
+            ) : null}
           </Layout.Title>
         </Layout.HeaderContent>
         <div /> {/* wraps the tabs below the page title */}