Files
2024-02-15 17:01:50 +00:00

132 lines
4.3 KiB
TypeScript

import type {InjectedRouter} from 'react-router';
import {browserHistory} from 'react-router';
import type {Location} from 'history';
import type {Client} from 'sentry/api';
import DeprecatedAsyncComponent from 'sentry/components/deprecatedAsyncComponent';
import PageFiltersContainer from 'sentry/components/organizations/pageFilters/container';
import {
getDatetimeFromState,
normalizeDateTimeString,
} from 'sentry/components/organizations/pageFilters/parse';
import {getPageFilterStorage} from 'sentry/components/organizations/pageFilters/persistence';
import type {Organization, PageFilters, SavedQuery} from 'sentry/types';
import EventView from 'sentry/utils/discover/eventView';
import withApi from 'sentry/utils/withApi';
import withOrganization from 'sentry/utils/withOrganization';
import withPageFilters from 'sentry/utils/withPageFilters';
import {Results} from './results';
type Props = {
api: Client;
loading: boolean;
location: Location;
organization: Organization;
router: InjectedRouter;
selection: PageFilters;
setSavedQuery: (savedQuery: SavedQuery) => void;
};
type HomepageQueryState = DeprecatedAsyncComponent['state'] & {
savedQuery?: SavedQuery | null;
starfishResult?: null;
};
class HomepageQueryAPI extends DeprecatedAsyncComponent<Props, HomepageQueryState> {
shouldReload = true;
componentDidUpdate(_, prevState) {
const hasFetchedSavedQuery = !prevState.savedQuery && this.state.savedQuery;
const hasInitiallyLoaded = prevState.loading && !this.state.loading;
const sidebarClicked = this.state.savedQuery && this.props.location.search === '';
const hasValidEventViewInURL = EventView.fromLocation(this.props.location).isValid();
if (
this.state.savedQuery &&
((hasInitiallyLoaded && hasFetchedSavedQuery && !hasValidEventViewInURL) ||
sidebarClicked)
) {
const eventView = EventView.fromSavedQuery(this.state.savedQuery);
const pageFilterState = getPageFilterStorage(this.props.organization.slug);
let query = {
...eventView.generateQueryStringObject(),
};
// Handle locked filters explicitly because we can't expect
// PageFilterContainer to properly overwrite stored filters
// when pushing the homepage query to the URL
if (pageFilterState?.pinnedFilters) {
pageFilterState.pinnedFilters.forEach(pinnedFilter => {
if (pinnedFilter === 'projects') {
query.project = pageFilterState.state.project?.map(String);
} else if (pinnedFilter === 'datetime') {
const {period, start, end, utc} = getDatetimeFromState(pageFilterState.state);
query = {
...query,
statsPeriod: period ?? undefined,
utc: utc?.toString(),
start: normalizeDateTimeString(start),
end: normalizeDateTimeString(end),
};
} else {
query[pinnedFilter] = pageFilterState.state[pinnedFilter];
}
});
}
browserHistory.replace({
...this.props.location,
query,
});
}
}
getEndpoints(): ReturnType<DeprecatedAsyncComponent['getEndpoints']> {
const {organization} = this.props;
const endpoints: ReturnType<DeprecatedAsyncComponent['getEndpoints']> = [];
if (organization.features.includes('discover-query')) {
endpoints.push([
'savedQuery',
`/organizations/${organization.slug}/discover/homepage/`,
]);
}
return endpoints;
}
onRequestSuccess({stateKey, data}) {
// No homepage query results in a 204, returning an empty string
if (stateKey === 'savedQuery' && data === '') {
this.setState({savedQuery: null});
}
}
setSavedQuery = (newSavedQuery?: SavedQuery) => {
this.setState({savedQuery: newSavedQuery});
};
renderBody(): React.ReactNode {
const {savedQuery, loading} = this.state;
return (
<Results
{...this.props}
savedQuery={savedQuery ?? undefined}
loading={loading}
setSavedQuery={this.setSavedQuery}
isHomepage
/>
);
}
}
function HomepageContainer(props: Props) {
return (
<PageFiltersContainer skipInitializeUrlParams>
<HomepageQueryAPI {...props} />
</PageFiltersContainer>
);
}
export default withApi(withOrganization(withPageFilters(HomepageContainer)));