eventDetails.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import {useLayoutEffect, useState} from 'react';
  2. import {useTheme} from '@emotion/react';
  3. import styled from '@emotion/styled';
  4. import {CommitRow} from 'sentry/components/commitRow';
  5. import {SuspectCommits} from 'sentry/components/events/suspectCommits';
  6. import {DatePageFilter} from 'sentry/components/organizations/datePageFilter';
  7. import {EnvironmentPageFilter} from 'sentry/components/organizations/environmentPageFilter';
  8. import {space} from 'sentry/styles/space';
  9. import useMedia from 'sentry/utils/useMedia';
  10. import usePageFilters from 'sentry/utils/usePageFilters';
  11. import {
  12. EventDetailsContent,
  13. type EventDetailsContentProps,
  14. } from 'sentry/views/issueDetails/groupEventDetails/groupEventDetailsContent';
  15. import {
  16. EventDetailsContext,
  17. useEventDetailsReducer,
  18. } from 'sentry/views/issueDetails/streamline/context';
  19. import {EventNavigation} from 'sentry/views/issueDetails/streamline/eventNavigation';
  20. import {EventSearch} from 'sentry/views/issueDetails/streamline/eventSearch';
  21. export function EventDetails({
  22. group,
  23. event,
  24. project,
  25. }: Required<EventDetailsContentProps>) {
  26. const [nav, setNav] = useState<HTMLDivElement | null>(null);
  27. const {selection} = usePageFilters();
  28. const {environments} = selection;
  29. const {eventDetails, dispatch} = useEventDetailsReducer();
  30. const theme = useTheme();
  31. const isScreenMedium = useMedia(`(max-width: ${theme.breakpoints.medium})`);
  32. useLayoutEffect(() => {
  33. const navHeight = nav?.offsetHeight ?? 0;
  34. const sidebarHeight = isScreenMedium ? theme.sidebar.mobileHeightNumber : 0;
  35. dispatch({
  36. type: 'UPDATE_DETAILS',
  37. state: {navScrollMargin: navHeight + sidebarHeight},
  38. });
  39. }, [nav, isScreenMedium, dispatch, theme.sidebar.mobileHeightNumber]);
  40. return (
  41. <EventDetailsContext.Provider value={{...eventDetails, dispatch}}>
  42. <SuspectCommits
  43. project={project}
  44. eventId={event.id}
  45. group={group}
  46. commitRow={CommitRow}
  47. />
  48. <FilterContainer>
  49. <EnvironmentPageFilter />
  50. <SearchFilter
  51. group={group}
  52. handleSearch={() => {}}
  53. environments={environments}
  54. query={''}
  55. />
  56. <DatePageFilter />
  57. </FilterContainer>
  58. <GroupContent navHeight={nav?.offsetHeight}>
  59. <FloatingEventNavigation event={event} group={group} ref={setNav} />
  60. <GroupContentPadding>
  61. <EventDetailsContent group={group} event={event} project={project} />
  62. </GroupContentPadding>
  63. </GroupContent>
  64. </EventDetailsContext.Provider>
  65. );
  66. }
  67. const FloatingEventNavigation = styled(EventNavigation)`
  68. position: sticky;
  69. top: 0;
  70. @media (max-width: ${p => p.theme.breakpoints.medium}) {
  71. top: ${p => p.theme.sidebar.mobileHeight};
  72. }
  73. background: ${p => p.theme.background};
  74. z-index: 100;
  75. border-radius: 6px 6px 0 0;
  76. `;
  77. const SearchFilter = styled(EventSearch)`
  78. border-radius: ${p => p.theme.borderRadius};
  79. `;
  80. const GroupContent = styled('div')<{navHeight?: number}>`
  81. border: 1px solid ${p => p.theme.translucentBorder};
  82. background: ${p => p.theme.background};
  83. border-radius: ${p => p.theme.borderRadius};
  84. position: relative;
  85. `;
  86. const GroupContentPadding = styled('div')`
  87. padding: ${space(1)} ${space(1.5)};
  88. `;
  89. const FilterContainer = styled('div')`
  90. display: grid;
  91. grid-template-columns: auto 1fr auto;
  92. gap: ${space(1)};
  93. `;