index.tsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import {Component, Fragment} from 'react';
  2. import type {InjectedRouter} from 'react-router';
  3. import type {Location} from 'history';
  4. import type {Client} from 'sentry/api';
  5. import EventsRequest from 'sentry/components/charts/eventsRequest';
  6. import LoadingPanel from 'sentry/components/charts/loadingPanel';
  7. import {HeaderTitle} from 'sentry/components/charts/styles';
  8. import {getInterval} from 'sentry/components/charts/utils';
  9. import {normalizeDateTimeParams} from 'sentry/components/organizations/pageFilters/parse';
  10. import Panel from 'sentry/components/panels/panel';
  11. import Placeholder from 'sentry/components/placeholder';
  12. import QuestionTooltip from 'sentry/components/questionTooltip';
  13. import {IconWarning} from 'sentry/icons';
  14. import type {Organization} from 'sentry/types';
  15. import {getUtcToLocalDateObject} from 'sentry/utils/dates';
  16. import type EventView from 'sentry/utils/discover/eventView';
  17. import getDynamicText from 'sentry/utils/getDynamicText';
  18. import withApi from 'sentry/utils/withApi';
  19. import {getAxisOptions} from '../data';
  20. import {DoubleHeaderContainer, ErrorPanel} from '../styles';
  21. import Chart from './chart';
  22. import Footer from './footer';
  23. type Props = {
  24. api: Client;
  25. eventView: EventView;
  26. location: Location;
  27. organization: Organization;
  28. router: InjectedRouter;
  29. };
  30. class Container extends Component<Props> {
  31. getChartParameters() {
  32. const {location, organization} = this.props;
  33. const options = getAxisOptions(organization);
  34. const left = options.find(opt => opt.value === location.query.left) || options[0];
  35. const right = options.find(opt => opt.value === location.query.right) || options[1];
  36. return [left, right];
  37. }
  38. render() {
  39. const {api, organization, location, eventView} = this.props;
  40. // construct request parameters for fetching chart data
  41. const globalSelection = eventView.getPageFilters();
  42. const start = globalSelection.datetime.start
  43. ? getUtcToLocalDateObject(globalSelection.datetime.start)
  44. : null;
  45. const end = globalSelection.datetime.end
  46. ? getUtcToLocalDateObject(globalSelection.datetime.end)
  47. : null;
  48. const {utc} = normalizeDateTimeParams(location.query);
  49. const axisOptions = this.getChartParameters();
  50. const apiPayload = eventView.getEventsAPIPayload(location);
  51. return (
  52. <Panel>
  53. <EventsRequest
  54. organization={organization}
  55. api={api}
  56. period={globalSelection.datetime.period}
  57. project={globalSelection.projects}
  58. environment={globalSelection.environments}
  59. team={apiPayload.team}
  60. start={start}
  61. end={end}
  62. interval={getInterval(
  63. {
  64. start,
  65. end,
  66. period: globalSelection.datetime.period,
  67. },
  68. 'high'
  69. )}
  70. showLoading={false}
  71. query={apiPayload.query}
  72. includePrevious={false}
  73. yAxis={axisOptions.map(opt => opt.value)}
  74. partial
  75. >
  76. {({loading, reloading, errored, results}) => {
  77. if (errored) {
  78. return (
  79. <ErrorPanel>
  80. <IconWarning color="gray300" size="lg" />
  81. </ErrorPanel>
  82. );
  83. }
  84. return (
  85. <Fragment>
  86. <DoubleHeaderContainer>
  87. {axisOptions.map((option, i) => (
  88. <div key={`${option.label}:${i}`}>
  89. <HeaderTitle>
  90. {option.label}
  91. <QuestionTooltip
  92. position="top"
  93. size="sm"
  94. title={option.tooltip}
  95. />
  96. </HeaderTitle>
  97. </div>
  98. ))}
  99. </DoubleHeaderContainer>
  100. {results ? (
  101. getDynamicText({
  102. value: (
  103. <Chart
  104. data={results}
  105. loading={loading || reloading}
  106. statsPeriod={globalSelection.datetime.period}
  107. start={start}
  108. end={end}
  109. utc={utc === 'true'}
  110. />
  111. ),
  112. fixed: <Placeholder height="200px" testId="skeleton-ui" />,
  113. })
  114. ) : (
  115. <LoadingPanel data-test-id="events-request-loading" />
  116. )}
  117. </Fragment>
  118. );
  119. }}
  120. </EventsRequest>
  121. <Footer
  122. api={api}
  123. leftAxis={axisOptions[0].value}
  124. rightAxis={axisOptions[1].value}
  125. organization={organization}
  126. eventView={eventView}
  127. location={location}
  128. />
  129. </Panel>
  130. );
  131. }
  132. }
  133. export default withApi(Container);