homepage.tsx 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import {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 withApi from 'sentry/utils/withApi';
  8. import withOrganization from 'sentry/utils/withOrganization';
  9. import withPageFilters from 'sentry/utils/withPageFilters';
  10. import {Results} from './results';
  11. type Props = {
  12. api: Client;
  13. loading: boolean;
  14. location: Location;
  15. organization: Organization;
  16. router: InjectedRouter;
  17. selection: PageFilters;
  18. setSavedQuery: (savedQuery: SavedQuery) => void;
  19. homepageQuery?: SavedQuery;
  20. savedQuery?: SavedQuery;
  21. };
  22. type HomepageQueryState = AsyncComponent['state'] & {
  23. key: number;
  24. savedQuery?: SavedQuery | null;
  25. };
  26. class HomepageQueryAPI extends AsyncComponent<Props, HomepageQueryState> {
  27. shouldReload = true;
  28. getEndpoints(): ReturnType<AsyncComponent['getEndpoints']> {
  29. const {organization, location} = this.props;
  30. const endpoints: ReturnType<AsyncComponent['getEndpoints']> = [];
  31. if (
  32. organization.features.includes('discover-query-builder-as-landing-page') &&
  33. organization.features.includes('discover-query')
  34. ) {
  35. endpoints.push([
  36. 'savedQuery',
  37. `/organizations/${organization.slug}/discover/homepage/`,
  38. ]);
  39. }
  40. // HACK: We're using state here to manage a component key so we can force remounting the entire discover result
  41. // This is because we need <Results> to rerun its constructor with the new homepage query to get it to display properly
  42. // We're checking to see that location.search is empty because that is the only time we should be fetching the homepage query
  43. if (location.search === '' && this.state) {
  44. this.setState({key: Date.now()});
  45. }
  46. return endpoints;
  47. }
  48. onRequestSuccess({stateKey, data}) {
  49. // No homepage query results in a 204, returning an empty string
  50. if (stateKey === 'savedQuery' && data === '') {
  51. this.setState({savedQuery: null});
  52. }
  53. }
  54. setSavedQuery = (newSavedQuery?: SavedQuery) => {
  55. this.setState({savedQuery: newSavedQuery});
  56. };
  57. renderBody(): React.ReactNode {
  58. const {savedQuery, loading} = this.state;
  59. return (
  60. <Results
  61. {...this.props}
  62. savedQuery={savedQuery ?? undefined}
  63. loading={loading}
  64. setSavedQuery={this.setSavedQuery}
  65. isHomepage
  66. key={`results-${this.state.key}`}
  67. />
  68. );
  69. }
  70. }
  71. function HomepageContainer(props: Props) {
  72. return (
  73. <PageFiltersContainer
  74. skipLoadLastUsed={
  75. props.organization.features.includes('global-views') && !!props.savedQuery
  76. }
  77. >
  78. <HomepageQueryAPI {...props} />
  79. </PageFiltersContainer>
  80. );
  81. }
  82. export default withApi(withOrganization(withPageFilters(HomepageContainer)));