123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- import styled from '@emotion/styled';
- import Feature from 'sentry/components/acl/feature';
- import * as Layout from 'sentry/components/layouts/thirds';
- import {NoAccess} from 'sentry/components/noAccess';
- import {DatePageFilter} from 'sentry/components/organizations/datePageFilter';
- import {EnvironmentPageFilter} from 'sentry/components/organizations/environmentPageFilter';
- import PageFilterBar from 'sentry/components/organizations/pageFilterBar';
- import {ProjectPageFilter} from 'sentry/components/organizations/projectPageFilter';
- import TransactionNameSearchBar from 'sentry/components/performance/searchBar';
- import * as TeamKeyTransactionManager from 'sentry/components/performance/teamKeyTransactionsManager';
- import {trackAnalytics} from 'sentry/utils/analytics';
- import {
- canUseMetricsData,
- useMEPSettingContext,
- } from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
- import {PageAlert, usePageAlert} from 'sentry/utils/performance/contexts/pageAlert';
- import {PerformanceDisplayProvider} from 'sentry/utils/performance/contexts/performanceDisplayContext';
- import {MutableSearch} from 'sentry/utils/tokenizeSearch';
- import {useLocation} from 'sentry/utils/useLocation';
- import {useNavigate} from 'sentry/utils/useNavigate';
- import useOrganization from 'sentry/utils/useOrganization';
- import useProjects from 'sentry/utils/useProjects';
- import {useUserTeams} from 'sentry/utils/useUserTeams';
- import * as ModuleLayout from 'sentry/views/insights/common/components/moduleLayout';
- import {ToolRibbon} from 'sentry/views/insights/common/components/ribbon';
- import {useOnboardingProject} from 'sentry/views/insights/common/queries/useOnboardingProject';
- import {ViewTrendsButton} from 'sentry/views/insights/common/viewTrendsButton';
- import {DomainOverviewPageProviders} from 'sentry/views/insights/pages/domainOverviewPageProviders';
- import {MobileHeader} from 'sentry/views/insights/pages/mobile/mobilePageHeader';
- import {
- MOBILE_LANDING_TITLE,
- OVERVIEW_PAGE_ALLOWED_OPS,
- } from 'sentry/views/insights/pages/mobile/settings';
- import {
- generateGenericPerformanceEventView,
- generateMobilePerformanceEventView,
- } from 'sentry/views/performance/data';
- import {checkIsReactNative} from 'sentry/views/performance/landing/utils';
- import {
- DoubleChartRow,
- TripleChartRow,
- } from 'sentry/views/performance/landing/widgets/components/widgetChartRow';
- import {filterAllowedChartsMetrics} from 'sentry/views/performance/landing/widgets/utils';
- import {PerformanceWidgetSetting} from 'sentry/views/performance/landing/widgets/widgetDefinitions';
- import Onboarding from 'sentry/views/performance/onboarding';
- import Table from 'sentry/views/performance/table';
- import {
- getTransactionSearchQuery,
- ProjectPerformanceType,
- } from 'sentry/views/performance/utils';
- const MOBILE_COLUMN_TITLES = [
- 'transaction',
- 'operation',
- 'project',
- 'tpm',
- 'slow frame %',
- 'frozen frame %',
- 'users',
- 'user misery',
- ];
- const REACT_NATIVE_COLUMN_TITLES = [
- 'transaction',
- 'operation',
- 'project',
- 'tpm',
- 'slow frame %',
- 'frozen frame %',
- 'stall %',
- 'users',
- 'user misery',
- ];
- function MobileOverviewPage() {
- const organization = useOrganization();
- const location = useLocation();
- const {setPageError} = usePageAlert();
- const {projects} = useProjects();
- const onboardingProject = useOnboardingProject();
- const navigate = useNavigate();
- const {teams} = useUserTeams();
- const mepSetting = useMEPSettingContext();
- const withStaticFilters = canUseMetricsData(organization);
- const eventView = generateMobilePerformanceEventView(
- location,
- projects,
- generateGenericPerformanceEventView(location, withStaticFilters, organization),
- withStaticFilters,
- organization
- );
- let columnTitles = checkIsReactNative(eventView)
- ? REACT_NATIVE_COLUMN_TITLES
- : MOBILE_COLUMN_TITLES;
- const doubleChartRowEventView = eventView.clone(); // some of the double chart rows rely on span metrics, so they can't be queried the same way
- const existingQuery = new MutableSearch(eventView.query);
- existingQuery.addDisjunctionFilterValues('transaction.op', OVERVIEW_PAGE_ALLOWED_OPS);
- eventView.query = existingQuery.formatString();
- const showOnboarding = onboardingProject !== undefined;
- const doubleChartRowCharts = [
- PerformanceWidgetSetting.MOST_SLOW_FRAMES,
- PerformanceWidgetSetting.MOST_FROZEN_FRAMES,
- ];
- const tripleChartRowCharts = filterAllowedChartsMetrics(
- organization,
- [
- PerformanceWidgetSetting.TPM_AREA,
- PerformanceWidgetSetting.DURATION_HISTOGRAM,
- PerformanceWidgetSetting.P50_DURATION_AREA,
- PerformanceWidgetSetting.P75_DURATION_AREA,
- PerformanceWidgetSetting.P95_DURATION_AREA,
- PerformanceWidgetSetting.P99_DURATION_AREA,
- PerformanceWidgetSetting.FAILURE_RATE_AREA,
- ],
- mepSetting
- );
- if (organization.features.includes('mobile-vitals')) {
- columnTitles = [...columnTitles.slice(0, 5), 'ttid', ...columnTitles.slice(5, 0)];
- tripleChartRowCharts.push(
- ...[
- PerformanceWidgetSetting.TIME_TO_INITIAL_DISPLAY,
- PerformanceWidgetSetting.TIME_TO_FULL_DISPLAY,
- ]
- );
- }
- if (organization.features.includes('insights-initial-modules')) {
- doubleChartRowCharts[0] = PerformanceWidgetSetting.SLOW_SCREENS_BY_TTID;
- }
- if (organization.features.includes('starfish-mobile-appstart')) {
- doubleChartRowCharts.push(
- PerformanceWidgetSetting.SLOW_SCREENS_BY_COLD_START,
- PerformanceWidgetSetting.SLOW_SCREENS_BY_WARM_START
- );
- }
- if (organization.features.includes('insights-initial-modules')) {
- doubleChartRowCharts.push(PerformanceWidgetSetting.MOST_TIME_CONSUMING_DOMAINS);
- }
- const sharedProps = {eventView, location, organization, withStaticFilters};
- const getFreeTextFromQuery = (query: string) => {
- const conditions = new MutableSearch(query);
- const transactionValues = conditions.getFilterValues('transaction');
- if (transactionValues.length) {
- return transactionValues[0];
- }
- if (conditions.freeText.length > 0) {
- // raw text query will be wrapped in wildcards in generatePerformanceEventView
- // so no need to wrap it here
- return conditions.freeText.join(' ');
- }
- return '';
- };
- function handleSearch(searchQuery: string) {
- trackAnalytics('performance.domains.mobile.search', {organization});
- navigate({
- pathname: location.pathname,
- query: {
- ...location.query,
- cursor: undefined,
- query: String(searchQuery).trim() || undefined,
- isDefaultQuery: false,
- },
- });
- }
- const derivedQuery = getTransactionSearchQuery(location, eventView.query);
- return (
- <Feature
- features="insights-domain-view"
- organization={organization}
- renderDisabled={NoAccess}
- >
- <MobileHeader
- headerTitle={MOBILE_LANDING_TITLE}
- headerActions={<ViewTrendsButton />}
- />
- <Layout.Body>
- <Layout.Main fullWidth>
- <ModuleLayout.Layout>
- <ModuleLayout.Full>
- <ToolRibbon>
- <PageFilterBar condensed>
- <ProjectPageFilter />
- <EnvironmentPageFilter />
- <DatePageFilter />
- </PageFilterBar>
- {!showOnboarding && (
- <StyledTransactionNameSearchBar
- organization={organization}
- eventView={eventView}
- onSearch={(query: string) => {
- handleSearch(query);
- }}
- query={getFreeTextFromQuery(derivedQuery)}
- />
- )}
- </ToolRibbon>
- </ModuleLayout.Full>
- <PageAlert />
- <ModuleLayout.Full>
- {!showOnboarding && (
- <PerformanceDisplayProvider
- value={{performanceType: ProjectPerformanceType.MOBILE}}
- >
- <TeamKeyTransactionManager.Provider
- organization={organization}
- teams={teams}
- selectedTeams={['myteams']}
- selectedProjects={eventView.project.map(String)}
- >
- <DoubleChartRow
- allowedCharts={doubleChartRowCharts}
- {...sharedProps}
- eventView={doubleChartRowEventView}
- />
- <TripleChartRow
- allowedCharts={tripleChartRowCharts}
- {...sharedProps}
- />
- <Table
- projects={projects}
- columnTitles={columnTitles}
- setError={setPageError}
- {...sharedProps}
- />
- </TeamKeyTransactionManager.Provider>
- </PerformanceDisplayProvider>
- )}
- {showOnboarding && (
- <Onboarding project={onboardingProject} organization={organization} />
- )}
- </ModuleLayout.Full>
- </ModuleLayout.Layout>
- </Layout.Main>
- </Layout.Body>
- </Feature>
- );
- }
- function MobileOverviewPageWithProviders() {
- return (
- <DomainOverviewPageProviders>
- <MobileOverviewPage />
- </DomainOverviewPageProviders>
- );
- }
- const StyledTransactionNameSearchBar = styled(TransactionNameSearchBar)`
- flex: 2;
- `;
- export default MobileOverviewPageWithProviders;
|