sessionsRequest.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import {Component} from 'react';
  2. import isEqual from 'lodash/isEqual';
  3. import omitBy from 'lodash/omitBy';
  4. import {addErrorMessage} from 'sentry/actionCreators/indicator';
  5. import {Client} from 'sentry/api';
  6. import {t} from 'sentry/locale';
  7. import {Organization, SessionApiResponse, SessionFieldWithOperation} from 'sentry/types';
  8. import {filterSessionsInTimeWindow, getSessionsInterval} from 'sentry/utils/sessions';
  9. const propNamesToIgnore = ['api', 'children', 'organization'];
  10. const omitIgnoredProps = (props: Props) =>
  11. omitBy(props, (_value, key) => propNamesToIgnore.includes(key));
  12. export type SessionsRequestRenderProps = {
  13. errored: boolean;
  14. loading: boolean;
  15. reloading: boolean;
  16. response: SessionApiResponse | null;
  17. };
  18. type Props = {
  19. api: Client;
  20. children: (renderProps: SessionsRequestRenderProps) => React.ReactNode;
  21. field: SessionFieldWithOperation[];
  22. organization: Organization;
  23. end?: string;
  24. environment?: string[];
  25. groupBy?: string[];
  26. interval?: string;
  27. isDisabled?: boolean;
  28. project?: number[];
  29. query?: string;
  30. shouldFilterSessionsInTimeWindow?: boolean;
  31. start?: string;
  32. statsPeriod?: string | null;
  33. };
  34. type State = {
  35. errored: boolean;
  36. reloading: boolean;
  37. response: SessionApiResponse | null;
  38. };
  39. class SessionsRequest extends Component<Props, State> {
  40. state: State = {
  41. reloading: false,
  42. errored: false,
  43. response: null,
  44. };
  45. componentDidMount() {
  46. this.fetchData();
  47. }
  48. componentDidUpdate(prevProps: Props) {
  49. if (isEqual(omitIgnoredProps(prevProps), omitIgnoredProps(this.props))) {
  50. return;
  51. }
  52. this.fetchData();
  53. }
  54. get path() {
  55. const {organization} = this.props;
  56. return `/organizations/${organization.slug}/sessions/`;
  57. }
  58. get baseQueryParams() {
  59. const {
  60. project,
  61. environment,
  62. field,
  63. statsPeriod,
  64. start,
  65. end,
  66. query,
  67. groupBy,
  68. interval,
  69. organization,
  70. } = this.props;
  71. return {
  72. project,
  73. environment,
  74. field,
  75. statsPeriod,
  76. query,
  77. groupBy,
  78. start,
  79. end,
  80. interval: interval
  81. ? interval
  82. : getSessionsInterval(
  83. {start, end, period: statsPeriod},
  84. {highFidelity: organization.features.includes('minute-resolution-sessions')}
  85. ),
  86. };
  87. }
  88. fetchData = async () => {
  89. const {api, isDisabled, shouldFilterSessionsInTimeWindow} = this.props;
  90. if (isDisabled) {
  91. return;
  92. }
  93. this.setState(state => ({
  94. reloading: state.response !== null,
  95. errored: false,
  96. }));
  97. try {
  98. const response: SessionApiResponse = await api.requestPromise(this.path, {
  99. query: this.baseQueryParams,
  100. });
  101. this.setState({
  102. reloading: false,
  103. response: shouldFilterSessionsInTimeWindow
  104. ? filterSessionsInTimeWindow(
  105. response,
  106. this.baseQueryParams.start,
  107. this.baseQueryParams.end
  108. )
  109. : response,
  110. });
  111. } catch (error) {
  112. addErrorMessage(error.responseJSON?.detail ?? t('Error loading health data'));
  113. this.setState({
  114. reloading: false,
  115. errored: true,
  116. });
  117. }
  118. };
  119. render() {
  120. const {reloading, errored, response} = this.state;
  121. const {children} = this.props;
  122. const loading = response === null;
  123. return children({
  124. loading,
  125. reloading,
  126. errored,
  127. response,
  128. });
  129. }
  130. }
  131. export default SessionsRequest;