previewTable.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import {Fragment} from 'react';
  2. import styled from '@emotion/styled';
  3. import {indexMembersByProject} from 'sentry/actionCreators/members';
  4. import EmptyStateWarning from 'sentry/components/emptyStateWarning';
  5. import GroupListHeader from 'sentry/components/issues/groupListHeader';
  6. import LoadingIndicator from 'sentry/components/loadingIndicator';
  7. import type {CursorHandler} from 'sentry/components/pagination';
  8. import Pagination from 'sentry/components/pagination';
  9. import Panel from 'sentry/components/panels/panel';
  10. import PanelBody from 'sentry/components/panels/panelBody';
  11. import StreamGroup from 'sentry/components/stream/group';
  12. import {t, tct} from 'sentry/locale';
  13. import GroupStore from 'sentry/stores/groupStore';
  14. import type {Group, Member} from 'sentry/types';
  15. type Props = {
  16. error: string | null;
  17. isLoading: boolean;
  18. issueCount: number;
  19. members: Member[] | undefined;
  20. onCursor: CursorHandler;
  21. page: number;
  22. pageLinks: string;
  23. previewGroups: string[];
  24. };
  25. function PreviewTable({
  26. previewGroups,
  27. members,
  28. pageLinks,
  29. onCursor,
  30. issueCount,
  31. page,
  32. isLoading,
  33. error,
  34. }: Props) {
  35. const renderBody = () => {
  36. if (isLoading) {
  37. return <LoadingIndicator />;
  38. }
  39. if (error || !members) {
  40. return (
  41. <EmptyStateWarning>
  42. <p>{error ? error : t('No preview available')}</p>
  43. </EmptyStateWarning>
  44. );
  45. }
  46. if (issueCount === 0) {
  47. return (
  48. <EmptyStateWarning>
  49. <p>{t("We couldn't find any issues that would've triggered your rule")}</p>
  50. </EmptyStateWarning>
  51. );
  52. }
  53. const memberList = indexMembersByProject(members);
  54. return previewGroups.map((id, index) => {
  55. const group = GroupStore.get(id) as Group | undefined;
  56. return (
  57. <StreamGroup
  58. index={index}
  59. key={id}
  60. id={id}
  61. hasGuideAnchor={false}
  62. memberList={group?.project ? memberList[group.project.slug] : undefined}
  63. displayReprocessingLayout={false}
  64. useFilteredStats
  65. withChart={false}
  66. canSelect={false}
  67. showLastTriggered
  68. withColumns={['assignee', 'event', 'lastTriggered', 'users']}
  69. />
  70. );
  71. });
  72. };
  73. const renderCaption = () => {
  74. if (isLoading || error || !previewGroups) {
  75. return null;
  76. }
  77. const pageIssues = page * 5 + previewGroups.length;
  78. return tct(`Showing [pageIssues] of [issueCount] issues`, {pageIssues, issueCount});
  79. };
  80. const renderPagination = () => {
  81. if (error) {
  82. return null;
  83. }
  84. return (
  85. <StyledPagination
  86. pageLinks={pageLinks}
  87. onCursor={onCursor}
  88. caption={renderCaption()}
  89. disabled={isLoading}
  90. />
  91. );
  92. };
  93. return (
  94. <Fragment>
  95. <Panel>
  96. <GroupListHeader
  97. withChart={false}
  98. withColumns={['assignee', 'event', 'lastTriggered', 'users']}
  99. />
  100. <PanelBody>{renderBody()}</PanelBody>
  101. </Panel>
  102. {renderPagination()}
  103. </Fragment>
  104. );
  105. }
  106. const StyledPagination = styled(Pagination)`
  107. margin-top: 0;
  108. `;
  109. export default PreviewTable;