import {FC, Fragment, useEffect, useRef} from 'react'; import {browserHistory} from 'react-router'; import styled from '@emotion/styled'; import {Location} from 'history'; import {openModal} from 'sentry/actionCreators/modal'; import Feature from 'sentry/components/acl/feature'; import Button from 'sentry/components/button'; import ButtonBar from 'sentry/components/buttonBar'; import DatePageFilter from 'sentry/components/datePageFilter'; import EnvironmentPageFilter from 'sentry/components/environmentPageFilter'; import SearchBar from 'sentry/components/events/searchBar'; import {GlobalSdkUpdateAlert} from 'sentry/components/globalSdkUpdateAlert'; import * as Layout from 'sentry/components/layouts/thirds'; import LoadingIndicator from 'sentry/components/loadingIndicator'; import PageFilterBar from 'sentry/components/organizations/pageFilterBar'; import PageHeading from 'sentry/components/pageHeading'; import TransactionNameSearchBar from 'sentry/components/performance/searchBar'; import * as TeamKeyTransactionManager from 'sentry/components/performance/teamKeyTransactionsManager'; import ProjectPageFilter from 'sentry/components/projectPageFilter'; import {MAX_QUERY_LENGTH} from 'sentry/constants'; import {IconSettings} from 'sentry/icons'; import {t} from 'sentry/locale'; import {PageContent} from 'sentry/styles/organization'; import space from 'sentry/styles/space'; import {Organization, PageFilters, Project} from 'sentry/types'; import EventView from 'sentry/utils/discover/eventView'; import {generateAggregateFields} from 'sentry/utils/discover/fields'; import {GenericQueryBatcher} from 'sentry/utils/performance/contexts/genericQueryBatcher'; import { PageErrorAlert, PageErrorProvider, } from 'sentry/utils/performance/contexts/pageError'; import useTeams from 'sentry/utils/useTeams'; import Onboarding from '../onboarding'; import {MetricsEventsDropdown} from '../transactionSummary/transactionOverview/metricEvents/metricsEventsDropdown'; import {getTransactionSearchQuery} from '../utils'; import {AllTransactionsView} from './views/allTransactionsView'; import {BackendView} from './views/backendView'; import {FrontendOtherView} from './views/frontendOtherView'; import {FrontendPageloadView} from './views/frontendPageloadView'; import {MobileView} from './views/mobileView'; import SamplingModal, {modalCss} from './samplingModal'; import { getDefaultDisplayForPlatform, getLandingDisplayFromParam, handleLandingDisplayChange, LANDING_DISPLAYS, LandingDisplayField, } from './utils'; type Props = { eventView: EventView; handleSearch: (searchQuery: string) => void; handleTrendsClick: () => void; location: Location; onboardingProject: Project | undefined; organization: Organization; projects: Project[]; selection: PageFilters; setError: (msg: string | undefined) => void; withStaticFilters: boolean; }; const fieldToViewMap: Record> = { [LandingDisplayField.ALL]: AllTransactionsView, [LandingDisplayField.BACKEND]: BackendView, [LandingDisplayField.FRONTEND_OTHER]: FrontendOtherView, [LandingDisplayField.FRONTEND_PAGELOAD]: FrontendPageloadView, [LandingDisplayField.MOBILE]: MobileView, }; export function PerformanceLanding(props: Props) { const { organization, location, eventView, projects, handleSearch, handleTrendsClick, onboardingProject, withStaticFilters, } = props; const {teams, initiallyLoaded} = useTeams({provideUserTeams: true}); const hasMounted = useRef(false); const paramLandingDisplay = getLandingDisplayFromParam(location); const defaultLandingDisplayForProjects = getDefaultDisplayForPlatform( projects, eventView ); const landingDisplay = paramLandingDisplay ?? defaultLandingDisplayForProjects; const showOnboarding = onboardingProject !== undefined; useEffect(() => { if (hasMounted.current) { browserHistory.replace({ pathname: location.pathname, query: { ...location.query, landingDisplay: undefined, }, }); } }, [eventView.project.join('.')]); useEffect(() => { hasMounted.current = true; }, []); const filterString = withStaticFilters ? 'transaction.duration:<15m' : getTransactionSearchQuery(location, eventView.query); const ViewComponent = fieldToViewMap[landingDisplay.field]; const fnOpenModal = () => { openModal( modalProps => ( {}} isMEPEnabled /> ), {modalCss, backdrop: 'static'} ); }; let pageFilters: React.ReactNode = ( ); if (showOnboarding) { pageFilters = {pageFilters}; } const SearchFilterContainer = organization.features.includes('performance-use-metrics') && !organization.features.includes('performance-transaction-name-only-search') ? SearchContainerWithFilterAndMetrics : SearchContainerWithFilter; return ( {t('Performance')} {!showOnboarding && (