groupListBody.tsx 3.6 KB

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