Browse Source

feat(replays): Replay layout add breadcrumbs to fullscreen mode (#58524)

Added collapsible breadcrumbs sidebar when in full screen mode.
Breadcrumbs list is searchable and filterable, and is open on default
when in full screen

<img width="1728" alt="image"
src="https://github.com/getsentry/sentry/assets/55311782/2c32cc56-cfd2-489b-b556-ee4cc14da536">
<img width="1728" alt="image"
src="https://github.com/getsentry/sentry/assets/55311782/67efd7cb-1ab4-4c2f-b34c-87f4df1602f4">

Closes https://github.com/getsentry/team-replay/issues/200
Catherine Lee 1 year ago
parent
commit
ca8fc28c52

+ 50 - 8
static/app/components/replays/replayView.tsx

@@ -1,12 +1,16 @@
-import {Fragment} from 'react';
+import {Fragment, useState} from 'react';
 import styled from '@emotion/styled';
 
+import {Button} from 'sentry/components/button';
 import ReplayController from 'sentry/components/replays/replayController';
 import ReplayCurrentUrl from 'sentry/components/replays/replayCurrentUrl';
 import ReplayPlayer from 'sentry/components/replays/replayPlayer';
+import {IconChevron} from 'sentry/icons';
+import {t} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
 import useOrganization from 'sentry/utils/useOrganization';
 import useIsFullscreen from 'sentry/utils/window/useIsFullscreen';
+import Breadcrumbs from 'sentry/views/replays/detail/breadcrumbs';
 import BrowserOSIcons from 'sentry/views/replays/detail/browserOSIcons';
 import FluidHeight from 'sentry/views/replays/detail/layout/fluidHeight';
 
@@ -18,16 +22,35 @@ function ReplayView({toggleFullscreen}: Props) {
   const organization = useOrganization();
   const hasNewTimeline = organization.features.includes('session-replay-new-timeline');
   const isFullscreen = useIsFullscreen();
+  const [isSidebarOpen, setIsSidebarOpen] = useState(true);
 
   return (
     <Fragment>
-      <ContextContainer>
-        <ReplayCurrentUrl />
-        <BrowserOSIcons />
-      </ContextContainer>
-      <Panel>
-        <ReplayPlayer />
-      </Panel>
+      <PlayerBreadcrumbContainer>
+        <PlayerContainer>
+          <ContextContainer>
+            <ReplayCurrentUrl />
+            <BrowserOSIcons />
+            {isFullscreen ? (
+              <Button
+                size="sm"
+                onClick={() => setIsSidebarOpen(!isSidebarOpen)}
+                icon={<IconChevron direction={isSidebarOpen ? 'right' : 'left'} />}
+              >
+                {isSidebarOpen ? t('Collapse Sidebar') : t('Open Sidebar')}
+              </Button>
+            ) : null}
+          </ContextContainer>
+          <Panel>
+            <ReplayPlayer />
+          </Panel>
+        </PlayerContainer>
+        {isFullscreen && isSidebarOpen ? (
+          <BreadcrumbContainer>
+            <Breadcrumbs />
+          </BreadcrumbContainer>
+        ) : null}
+      </PlayerBreadcrumbContainer>
       {isFullscreen || !hasNewTimeline ? (
         <ReplayController toggleFullscreen={toggleFullscreen} />
       ) : null}
@@ -50,4 +73,23 @@ const ContextContainer = styled('div')`
   gap: ${space(1)};
 `;
 
+const PlayerContainer = styled('div')`
+  display: grid;
+  grid-auto-flow: row;
+  grid-template-rows: auto 1fr;
+  gap: ${space(1)};
+  flex-grow: 1;
+`;
+
+const BreadcrumbContainer = styled('div')`
+  width: 25%;
+`;
+
+const PlayerBreadcrumbContainer = styled('div')`
+  display: flex;
+  flex-direction: row;
+  height: 100%;
+  gap: ${space(1)};
+`;
+
 export default ReplayView;

+ 1 - 1
static/app/utils/window/useIsFullscreen.tsx

@@ -8,7 +8,7 @@ import screenfull from 'screenfull';
  * as part of your component render method.
  */
 export default function useIsFullscreen() {
-  const [isFullscreen, setIsFullscreen] = useState(false);
+  const [isFullscreen, setIsFullscreen] = useState(screenfull.isFullscreen);
 
   useEffect(() => {
     if (!screenfull.isEnabled) {