import * as React from 'react'; import {browserHistory, InjectedRouter} from 'react-router'; import styled from '@emotion/styled'; import {Location} from 'history'; import omit from 'lodash/omit'; import Feature from 'app/components/acl/feature'; import Alert from 'app/components/alert'; import Button from 'app/components/button'; import ButtonBar from 'app/components/buttonBar'; import {CreateAlertFromViewButton} from 'app/components/createAlertButton'; import SearchBar from 'app/components/events/searchBar'; import * as Layout from 'app/components/layouts/thirds'; import {getParams} from 'app/components/organizations/globalSelectionHeader/getParams'; import * as TeamKeyTransactionManager from 'app/components/performance/teamKeyTransactionsManager'; import {IconChevron} from 'app/icons'; import {IconFlag} from 'app/icons/iconFlag'; import {t} from 'app/locale'; import space from 'app/styles/space'; import {Organization, Project, Team} from 'app/types'; import {generateQueryWithTag} from 'app/utils'; import EventView from 'app/utils/discover/eventView'; import {WebVital} from 'app/utils/discover/fields'; import {isActiveSuperuser} from 'app/utils/isActiveSuperuser'; import {decodeScalar} from 'app/utils/queryString'; import {MutableSearch} from 'app/utils/tokenizeSearch'; import withProjects from 'app/utils/withProjects'; import withTeams from 'app/utils/withTeams'; import Breadcrumb from '../breadcrumb'; import {getTransactionSearchQuery} from '../utils'; import Table from './table'; import {vitalDescription, vitalMap} from './utils'; import VitalChart from './vitalChart'; import VitalInfo from './vitalInfo'; const FRONTEND_VITALS = [WebVital.FCP, WebVital.LCP, WebVital.FID, WebVital.CLS]; type Props = { location: Location; eventView: EventView; organization: Organization; projects: Project[]; teams: Team[]; router: InjectedRouter; vitalName: WebVital; }; type State = { incompatibleAlertNotice: React.ReactNode; error: string | undefined; }; function getSummaryConditions(query: string) { const parsed = new MutableSearch(query); parsed.freeText = []; return parsed.formatString(); } class VitalDetailContent extends React.Component { state: State = { incompatibleAlertNotice: null, error: undefined, }; handleSearch = (query: string) => { const {location} = this.props; const queryParams = getParams({ ...(location.query || {}), query, }); // do not propagate pagination when making a new search const searchQueryParams = omit(queryParams, 'cursor'); browserHistory.push({ pathname: location.pathname, query: searchQueryParams, }); }; generateTagUrl = (key: string, value: string) => { const {location} = this.props; const query = generateQueryWithTag(location.query, {key, value}); return { ...location, query, }; }; handleIncompatibleQuery: React.ComponentProps< typeof CreateAlertFromViewButton >['onIncompatibleQuery'] = (incompatibleAlertNoticeFn, _errors) => { const incompatibleAlertNotice = incompatibleAlertNoticeFn(() => this.setState({incompatibleAlertNotice: null}) ); this.setState({incompatibleAlertNotice}); }; renderCreateAlertButton() { const {eventView, organization, projects} = this.props; return ( {}} referrer="performance" /> ); } renderVitalSwitcher() { const {vitalName, location} = this.props; const position = FRONTEND_VITALS.indexOf(vitalName); if (position < 0) { return null; } const previousDisabled = position === 0; const nextDisabled = position === FRONTEND_VITALS.length - 1; const switchVital = newVitalName => { return () => { browserHistory.push({ pathname: location.pathname, query: { ...location.query, vitalName: newVitalName, }, }); }; }; return (