groupUserFeedback.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import {Fragment} from 'react';
  2. import {css} from '@emotion/react';
  3. import styled from '@emotion/styled';
  4. import {EventUserFeedback} from 'sentry/components/events/userFeedback';
  5. import * as Layout from 'sentry/components/layouts/thirds';
  6. import LoadingError from 'sentry/components/loadingError';
  7. import LoadingIndicator from 'sentry/components/loadingIndicator';
  8. import Pagination from 'sentry/components/pagination';
  9. import {t} from 'sentry/locale';
  10. import {space} from 'sentry/styles/space';
  11. import {useLocation} from 'sentry/utils/useLocation';
  12. import useOrganization from 'sentry/utils/useOrganization';
  13. import {useParams} from 'sentry/utils/useParams';
  14. import {useGroup} from 'sentry/views/issueDetails/useGroup';
  15. import {useGroupUserFeedback} from 'sentry/views/issueDetails/useGroupUserFeedback';
  16. import {useHasStreamlinedUI} from 'sentry/views/issueDetails/utils';
  17. import {UserFeedbackEmpty} from 'sentry/views/userFeedback/userFeedbackEmpty';
  18. function GroupUserFeedback() {
  19. const organization = useOrganization();
  20. const hasStreamlinedUI = useHasStreamlinedUI();
  21. const location = useLocation();
  22. const params = useParams<{groupId: string}>();
  23. const {
  24. data: group,
  25. isPending: isPendingGroup,
  26. isError: isErrorGroup,
  27. refetch: refetchGroup,
  28. } = useGroup({
  29. groupId: params.groupId,
  30. });
  31. const {
  32. data: reportList,
  33. isPending,
  34. isError,
  35. refetch,
  36. getResponseHeader,
  37. } = useGroupUserFeedback({
  38. groupId: params.groupId,
  39. query: {
  40. cursor: location.query.cursor as string | undefined,
  41. },
  42. });
  43. if (isError || isErrorGroup) {
  44. return (
  45. <LoadingError
  46. onRetry={() => {
  47. refetch();
  48. refetchGroup();
  49. }}
  50. />
  51. );
  52. }
  53. if (isPending || isPendingGroup) {
  54. return (
  55. <StyledLayoutBody hasStreamlinedUI={hasStreamlinedUI}>
  56. <Layout.Main fullWidth>
  57. <LoadingIndicator />
  58. </Layout.Main>
  59. </StyledLayoutBody>
  60. );
  61. }
  62. const pageLinks = getResponseHeader?.('Link');
  63. const hasUserFeedback = group.project.hasUserReports;
  64. return (
  65. <StyledLayoutBody hasStreamlinedUI={hasStreamlinedUI}>
  66. <Layout.Main fullWidth>
  67. {hasStreamlinedUI && hasUserFeedback && (
  68. <FilterMessage>
  69. {t('The feedback shown below is not subject to search filters.')}
  70. <StyledBreak />
  71. </FilterMessage>
  72. )}
  73. {reportList.length === 0 ? (
  74. <UserFeedbackEmpty projectIds={[group.project.id]} issueTab />
  75. ) : (
  76. <Fragment>
  77. {reportList.map((item, idx) => (
  78. <StyledEventUserFeedback
  79. key={idx}
  80. report={item}
  81. orgSlug={organization.slug}
  82. issueId={params.groupId}
  83. />
  84. ))}
  85. <Pagination pageLinks={pageLinks} />
  86. </Fragment>
  87. )}
  88. </Layout.Main>
  89. </StyledLayoutBody>
  90. );
  91. }
  92. const StyledEventUserFeedback = styled(EventUserFeedback)`
  93. margin-bottom: ${space(2)};
  94. `;
  95. const StyledLayoutBody = styled(Layout.Body)<{hasStreamlinedUI?: boolean}>`
  96. ${p =>
  97. p.hasStreamlinedUI &&
  98. css`
  99. border: 1px solid ${p.theme.border};
  100. border-radius: ${p.theme.borderRadius};
  101. padding: ${space(1.5)} 0;
  102. @media (min-width: ${p.theme.breakpoints.medium}) {
  103. padding: ${space(1.5)};
  104. }
  105. `}
  106. `;
  107. const FilterMessage = styled('div')`
  108. color: ${p => p.theme.subText};
  109. `;
  110. const StyledBreak = styled('hr')`
  111. margin-top: ${space(1)};
  112. margin-bottom: ${space(1)};
  113. border-color: ${p => p.theme.border};
  114. `;
  115. export default GroupUserFeedback;