groupListBody.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import type {IndexedMembersByProject} from 'sentry/actionCreators/members';
  2. import LoadingError from 'sentry/components/loadingError';
  3. import LoadingIndicator from 'sentry/components/loadingIndicator';
  4. import PanelBody from 'sentry/components/panels/panelBody';
  5. import StreamGroup from 'sentry/components/stream/group';
  6. import GroupStore from 'sentry/stores/groupStore';
  7. import type {Group} from 'sentry/types';
  8. import theme from 'sentry/utils/theme';
  9. import useApi from 'sentry/utils/useApi';
  10. import useMedia from 'sentry/utils/useMedia';
  11. import useOrganization from 'sentry/utils/useOrganization';
  12. import {useSyncedLocalStorageState} from 'sentry/utils/useSyncedLocalStorageState';
  13. import NoGroupsHandler from './noGroupsHandler';
  14. import {SAVED_SEARCHES_SIDEBAR_OPEN_LOCALSTORAGE_KEY} from './utils';
  15. type GroupListBodyProps = {
  16. displayReprocessingLayout: boolean;
  17. error: string | null;
  18. groupIds: string[];
  19. groupStatsPeriod: string;
  20. loading: boolean;
  21. memberList: IndexedMembersByProject;
  22. query: string;
  23. refetchGroups: () => void;
  24. selectedProjectIds: number[];
  25. };
  26. type GroupListProps = {
  27. displayReprocessingLayout: boolean;
  28. groupIds: string[];
  29. groupStatsPeriod: string;
  30. memberList: IndexedMembersByProject;
  31. query: string;
  32. };
  33. function GroupListBody({
  34. groupIds,
  35. memberList,
  36. query,
  37. displayReprocessingLayout,
  38. groupStatsPeriod,
  39. loading,
  40. error,
  41. refetchGroups,
  42. selectedProjectIds,
  43. }: GroupListBodyProps) {
  44. const api = useApi();
  45. const organization = useOrganization();
  46. if (loading) {
  47. return <LoadingIndicator hideMessage />;
  48. }
  49. if (error) {
  50. return <LoadingError message={error} onRetry={refetchGroups} />;
  51. }
  52. if (!groupIds.length) {
  53. return (
  54. <NoGroupsHandler
  55. api={api}
  56. organization={organization}
  57. query={query}
  58. selectedProjectIds={selectedProjectIds}
  59. groupIds={groupIds}
  60. />
  61. );
  62. }
  63. return (
  64. <GroupList
  65. groupIds={groupIds}
  66. memberList={memberList}
  67. query={query}
  68. displayReprocessingLayout={displayReprocessingLayout}
  69. groupStatsPeriod={groupStatsPeriod}
  70. />
  71. );
  72. }
  73. function GroupList({
  74. groupIds,
  75. memberList,
  76. query,
  77. displayReprocessingLayout,
  78. groupStatsPeriod,
  79. }: GroupListProps) {
  80. const [isSavedSearchesOpen] = useSyncedLocalStorageState(
  81. SAVED_SEARCHES_SIDEBAR_OPEN_LOCALSTORAGE_KEY,
  82. false
  83. );
  84. const topIssue = groupIds[0];
  85. const canSelect = !useMedia(
  86. `(max-width: ${
  87. isSavedSearchesOpen ? theme.breakpoints.large : theme.breakpoints.small
  88. })`
  89. );
  90. return (
  91. <PanelBody>
  92. {groupIds.map((id, index) => {
  93. const hasGuideAnchor = id === topIssue;
  94. const group = GroupStore.get(id) as Group | undefined;
  95. return (
  96. <StreamGroup
  97. index={index}
  98. key={id}
  99. id={id}
  100. statsPeriod={groupStatsPeriod}
  101. query={query}
  102. hasGuideAnchor={hasGuideAnchor}
  103. memberList={group?.project ? memberList[group.project.slug] : undefined}
  104. displayReprocessingLayout={displayReprocessingLayout}
  105. useFilteredStats
  106. canSelect={canSelect}
  107. narrowGroups={isSavedSearchesOpen}
  108. />
  109. );
  110. })}
  111. </PanelBody>
  112. );
  113. }
  114. export default GroupListBody;