import {Component, Fragment} from 'react'; import type {InjectedRouter} from 'react-router'; import styled from '@emotion/styled'; import type {Location} from 'history'; import {stringify} from 'query-string'; import {fetchHomepageQuery} from 'sentry/actionCreators/discoverHomepageQueries'; import {fetchSavedQuery} from 'sentry/actionCreators/discoverSavedQueries'; import type {Client} from 'sentry/api'; import Feature from 'sentry/components/acl/feature'; import GuideAnchor from 'sentry/components/assistant/guideAnchor'; import * as Layout from 'sentry/components/layouts/thirds'; import {PageHeadingQuestionTooltip} from 'sentry/components/pageHeadingQuestionTooltip'; import TimeSince from 'sentry/components/timeSince'; import {t} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import type {Organization, SavedQuery} from 'sentry/types'; import EventView from 'sentry/utils/discover/eventView'; import type {SavedQueryDatasets} from 'sentry/utils/discover/types'; import withApi from 'sentry/utils/withApi'; import Banner from './banner'; import DiscoverBreadcrumb from './breadcrumb'; import {DEFAULT_EVENT_VIEW} from './data'; import EventInputName from './eventInputName'; import SavedQueryButtonGroup from './savedQuery'; type Props = { api: Client; errorCode: number; eventView: EventView; location: Location; organization: Organization; router: InjectedRouter; setSavedQuery: (savedQuery?: SavedQuery) => void; yAxis: string[]; isHomepage?: boolean; splitDecision?: SavedQueryDatasets; }; type State = { homepageQuery: SavedQuery | undefined; loading: boolean; savedQuery: SavedQuery | undefined; }; class ResultsHeader extends Component { state: State = { homepageQuery: undefined, savedQuery: undefined, loading: true, }; componentDidMount() { const {eventView, isHomepage} = this.props; const {loading} = this.state; if (!isHomepage && eventView.id) { this.fetchData(); } else if (eventView.id === undefined && loading) { // If this is a new query, there's nothing to load this.setState({loading: false}); } if (isHomepage) { this.fetchHomepageQueryData(); } } componentDidUpdate(prevProps: Props) { if ( prevProps.eventView && this.props.eventView && prevProps.eventView.id !== this.props.eventView.id ) { this.fetchData(); } } fetchData() { const {api, eventView, organization, isHomepage} = this.props; if (!isHomepage && typeof eventView.id === 'string') { this.setState({loading: true}); fetchSavedQuery(api, organization.slug, eventView.id).then(savedQuery => { this.setState({savedQuery, loading: false}); }); } } fetchHomepageQueryData() { const {api, organization} = this.props; this.setState({loading: true}); fetchHomepageQuery(api, organization.slug).then(homepageQuery => { this.setState({homepageQuery, loading: false}); }); } renderAuthor() { const {eventView, isHomepage} = this.props; const {savedQuery} = this.state; // No saved query in use. if (!eventView.id || isHomepage) { return null; } let createdBy = ' \u2014 '; let lastEdit: React.ReactNode = ' \u2014 '; if (savedQuery !== undefined) { createdBy = savedQuery.createdBy?.email || '\u2014'; lastEdit = ; } return ( {t('Created by:')} {createdBy} | {t('Last edited:')} {lastEdit} ); } renderBanner() { const {location, organization} = this.props; const eventView = EventView.fromNewQueryWithLocation(DEFAULT_EVENT_VIEW, location); const to = eventView.getResultsViewUrlTarget(organization.slug); const resultsUrl = `${to.pathname}?${stringify(to.query)}`; return ( ); } render() { const { organization, location, errorCode, eventView, yAxis, router, setSavedQuery, isHomepage, splitDecision, } = this.props; const {savedQuery, loading, homepageQuery} = this.state; return ( {isHomepage ? ( {t('Discover')} ) : ( )} {this.renderAuthor()} = 400 && errorCode < 500} updateCallback={() => this.fetchData()} yAxis={yAxis} router={router} isHomepage={isHomepage} splitDecision={splitDecision} setHomepageQuery={updatedHomepageQuery => { this.setState({homepageQuery: updatedHomepageQuery}); if (isHomepage) { setSavedQuery(updatedHomepageQuery); } }} homepageQuery={homepageQuery} /> {isHomepage && this.renderBanner()} ); } } const Subtitle = styled('h4')` font-size: ${p => p.theme.fontSizeLarge}; font-weight: ${p => p.theme.fontWeightNormal}; color: ${p => p.theme.gray300}; margin: ${space(0.5)} 0 0 0; `; const BannerWrapper = styled('div')` grid-column: 1 / -1; `; export default withApi(ResultsHeader);