groupUserFeedback.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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 {space} from 'sentry/styles/space';
  10. import {useLocation} from 'sentry/utils/useLocation';
  11. import useOrganization from 'sentry/utils/useOrganization';
  12. import {useParams} from 'sentry/utils/useParams';
  13. import {useGroup} from 'sentry/views/issueDetails/useGroup';
  14. import {useGroupUserFeedback} from 'sentry/views/issueDetails/useGroupUserFeedback';
  15. import {useHasStreamlinedUI} from 'sentry/views/issueDetails/utils';
  16. import {UserFeedbackEmpty} from 'sentry/views/userFeedback/userFeedbackEmpty';
  17. function GroupUserFeedback() {
  18. const organization = useOrganization();
  19. const hasStreamlinedUI = useHasStreamlinedUI();
  20. const location = useLocation();
  21. const params = useParams<{groupId: string}>();
  22. const {
  23. data: group,
  24. isPending: isPendingGroup,
  25. isError: isErrorGroup,
  26. refetch: refetchGroup,
  27. } = useGroup({
  28. groupId: params.groupId,
  29. });
  30. const {
  31. data: reportList,
  32. isPending,
  33. isError,
  34. refetch,
  35. getResponseHeader,
  36. } = useGroupUserFeedback({
  37. groupId: params.groupId,
  38. query: {
  39. cursor: location.query.cursor as string | undefined,
  40. },
  41. });
  42. if (isError || isErrorGroup) {
  43. return (
  44. <LoadingError
  45. onRetry={() => {
  46. refetch();
  47. refetchGroup();
  48. }}
  49. />
  50. );
  51. }
  52. if (isPending || isPendingGroup) {
  53. return (
  54. <StyledLayoutBody hasStreamlinedUI={hasStreamlinedUI}>
  55. <Layout.Main fullWidth>
  56. <LoadingIndicator />
  57. </Layout.Main>
  58. </StyledLayoutBody>
  59. );
  60. }
  61. const pageLinks = getResponseHeader?.('Link');
  62. return (
  63. <StyledLayoutBody hasStreamlinedUI={hasStreamlinedUI}>
  64. <Layout.Main fullWidth>
  65. {reportList.length === 0 ? (
  66. <UserFeedbackEmpty projectIds={[group.project.id]} issueTab />
  67. ) : (
  68. <Fragment>
  69. {reportList.map((item, idx) => (
  70. <StyledEventUserFeedback
  71. key={idx}
  72. report={item}
  73. orgSlug={organization.slug}
  74. issueId={params.groupId}
  75. />
  76. ))}
  77. <Pagination pageLinks={pageLinks} />
  78. </Fragment>
  79. )}
  80. </Layout.Main>
  81. </StyledLayoutBody>
  82. );
  83. }
  84. const StyledEventUserFeedback = styled(EventUserFeedback)`
  85. margin-bottom: ${space(2)};
  86. `;
  87. const StyledLayoutBody = styled(Layout.Body)<{hasStreamlinedUI?: boolean}>`
  88. ${p =>
  89. p.hasStreamlinedUI &&
  90. css`
  91. border: 1px solid ${p.theme.border};
  92. border-radius: ${p.theme.borderRadius};
  93. padding: ${space(2)} 0;
  94. @media (min-width: ${p.theme.breakpoints.medium}) {
  95. padding: ${space(2)} ${space(2)};
  96. }
  97. `}
  98. `;
  99. export default GroupUserFeedback;