asideTabs_v2.tsx 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import React from 'react';
  2. import styled from '@emotion/styled';
  3. import ErrorBoundary from 'sentry/components/errorBoundary';
  4. import NavTabs from 'sentry/components/navTabs';
  5. import Placeholder from 'sentry/components/placeholder';
  6. import {useReplayContext} from 'sentry/components/replays/replayContext';
  7. import ReplayView from 'sentry/components/replays/replayView';
  8. import {t} from 'sentry/locale';
  9. import useFullscreen from 'sentry/utils/replays/hooks/useFullscreen';
  10. import useUrlParams from 'sentry/utils/replays/hooks/useUrlParams';
  11. import ReplayReader from 'sentry/utils/replays/replayReader';
  12. import Breadcrumbs from 'sentry/views/replays/detail/breadcrumbs';
  13. import TagPanel from '../tagPanel';
  14. import {BreadcrumbSection, VideoSection} from './pageSections';
  15. import ResizePanel from './resizePanel';
  16. type Props = {
  17. showCrumbs?: boolean;
  18. showVideo?: boolean;
  19. };
  20. const TABS = {
  21. video: t('Replay'),
  22. tags: t('Tags'),
  23. };
  24. function AsideTabsV2({showCrumbs = true, showVideo = true}: Props) {
  25. const {ref: fullscreenRef, isFullscreen, toggle: toggleFullscreen} = useFullscreen();
  26. const {replay} = useReplayContext();
  27. const {getParamValue, setParamValue} = useUrlParams('t_side', 'video');
  28. const active = getParamValue();
  29. const renderTabContent = (key: string, loadedReplay: ReplayReader) => {
  30. if (key === 'tags') {
  31. return <TagPanel replay={loadedReplay} />;
  32. }
  33. return (
  34. <React.Fragment>
  35. {showVideo ? (
  36. <ResizePanel direction="s" style={{height: '325px'}}>
  37. <Container>
  38. <VideoSection ref={fullscreenRef}>
  39. <ErrorBoundary mini>
  40. <ReplayView
  41. toggleFullscreen={toggleFullscreen}
  42. isFullscreen={isFullscreen}
  43. />
  44. </ErrorBoundary>
  45. </VideoSection>
  46. </Container>
  47. </ResizePanel>
  48. ) : null}
  49. {showCrumbs ? (
  50. <BreadcrumbSection>
  51. <ErrorBoundary mini>
  52. <Breadcrumbs />
  53. </ErrorBoundary>
  54. </BreadcrumbSection>
  55. ) : null}
  56. </React.Fragment>
  57. );
  58. };
  59. return (
  60. <React.Fragment>
  61. <NavTabs underlined>
  62. {Object.entries(TABS).map(([tab, label]) => {
  63. return (
  64. <li key={tab} className={active === tab ? 'active' : ''}>
  65. <a onClick={() => setParamValue(tab)}>{label}</a>
  66. </li>
  67. );
  68. })}
  69. </NavTabs>
  70. {replay ? renderTabContent(active, replay) : <Placeholder height="100%" />}
  71. </React.Fragment>
  72. );
  73. }
  74. const Container = styled('div')`
  75. height: 100%;
  76. /* TODO(replays): calc max height so the user can't resize infinitely but always showing both elements */
  77. max-height: 50vh;
  78. `;
  79. export default AsideTabsV2;