homepage.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import {browserHistory, InjectedRouter} from 'react-router';
  2. import {Location} from 'history';
  3. import {Client} from 'sentry/api';
  4. import AsyncComponent from 'sentry/components/asyncComponent';
  5. import PageFiltersContainer from 'sentry/components/organizations/pageFilters/container';
  6. import {Organization, PageFilters, SavedQuery} from 'sentry/types';
  7. import EventView from 'sentry/utils/discover/eventView';
  8. import withApi from 'sentry/utils/withApi';
  9. import withOrganization from 'sentry/utils/withOrganization';
  10. import withPageFilters from 'sentry/utils/withPageFilters';
  11. import {Results} from './results';
  12. type Props = {
  13. api: Client;
  14. loading: boolean;
  15. location: Location;
  16. organization: Organization;
  17. router: InjectedRouter;
  18. selection: PageFilters;
  19. setSavedQuery: (savedQuery: SavedQuery) => void;
  20. };
  21. type HomepageQueryState = AsyncComponent['state'] & {
  22. savedQuery?: SavedQuery | null;
  23. };
  24. class HomepageQueryAPI extends AsyncComponent<Props, HomepageQueryState> {
  25. shouldReload = true;
  26. componentDidUpdate(prevProps, prevState) {
  27. const hasFetchedSavedQuery = !prevState.savedQuery && this.state.savedQuery;
  28. const hasInitiallyLoaded = prevState.loading && !this.state.loading;
  29. const sidebarClicked = this.state.savedQuery && this.props.location.search === '';
  30. const hasValidEventViewInURL = EventView.fromLocation(this.props.location).isValid();
  31. if (
  32. this.state.savedQuery &&
  33. ((hasInitiallyLoaded && hasFetchedSavedQuery && !hasValidEventViewInURL) ||
  34. sidebarClicked)
  35. ) {
  36. const eventView = EventView.fromSavedQuery(this.state.savedQuery);
  37. browserHistory.replace(
  38. eventView.getResultsViewUrlTarget(this.props.organization.slug, true)
  39. );
  40. }
  41. super.componentDidUpdate(prevProps, prevState);
  42. }
  43. getEndpoints(): ReturnType<AsyncComponent['getEndpoints']> {
  44. const {organization} = this.props;
  45. const endpoints: ReturnType<AsyncComponent['getEndpoints']> = [];
  46. if (
  47. organization.features.includes('discover-query-builder-as-landing-page') &&
  48. organization.features.includes('discover-query')
  49. ) {
  50. endpoints.push([
  51. 'savedQuery',
  52. `/organizations/${organization.slug}/discover/homepage/`,
  53. ]);
  54. }
  55. return endpoints;
  56. }
  57. onRequestSuccess({stateKey, data}) {
  58. // No homepage query results in a 204, returning an empty string
  59. if (stateKey === 'savedQuery' && data === '') {
  60. this.setState({savedQuery: null});
  61. }
  62. }
  63. setSavedQuery = (newSavedQuery?: SavedQuery) => {
  64. this.setState({savedQuery: newSavedQuery});
  65. };
  66. renderBody(): React.ReactNode {
  67. const {savedQuery, loading} = this.state;
  68. return (
  69. <Results
  70. {...this.props}
  71. savedQuery={savedQuery ?? undefined}
  72. loading={loading}
  73. setSavedQuery={this.setSavedQuery}
  74. isHomepage
  75. />
  76. );
  77. }
  78. }
  79. function HomepageContainer(props: Props) {
  80. return (
  81. <PageFiltersContainer
  82. skipLoadLastUsed={props.organization.features.includes('global-views')}
  83. skipInitializeUrlParams
  84. >
  85. <HomepageQueryAPI {...props} />
  86. </PageFiltersContainer>
  87. );
  88. }
  89. export default withApi(withOrganization(withPageFilters(HomepageContainer)));