Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions static/app/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import withDomainRequired from 'sentry/utils/withDomainRequired';
import App from 'sentry/views/app';
import AuthLayout from 'sentry/views/auth/layout';
import {MODULE_BASE_URLS} from 'sentry/views/insights/common/utils/useModuleURL';
import {SUMMARY_PAGE_BASE_URL} from 'sentry/views/insights/mobile/screenRendering/settings';
import {AI_LANDING_SUB_PATH} from 'sentry/views/insights/pages/ai/settings';
import {BACKEND_LANDING_SUB_PATH} from 'sentry/views/insights/pages/backend/settings';
import {FRONTEND_LANDING_SUB_PATH} from 'sentry/views/insights/pages/frontend/settings';
Expand Down Expand Up @@ -1759,6 +1760,25 @@ function buildRoutes() {
)}
/>
</Route>
<Route path={`${MODULE_BASE_URLS[ModuleName.SCREEN_RENDERING]}/`}>
<IndexRoute
component={make(
() =>
import(
'sentry/views/insights/mobile/screenRendering/screenRenderingLandingPage'
)
)}
/>
<Route
path={`${SUMMARY_PAGE_BASE_URL}/`}
component={make(
() =>
import(
'sentry/views/insights/mobile/screenRendering/screenRenderingSummaryPage'
)
)}
/>
</Route>
<Route path={`${MODULE_BASE_URLS[ModuleName.APP_START]}/`}>
<IndexRoute
component={make(
Expand Down
2 changes: 2 additions & 0 deletions static/app/utils/analytics/insightAnalyticEvents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export type InsightEventParameters = {
'insight.page_loads.http': {has_ever_sent_data: boolean};
'insight.page_loads.queue': {has_ever_sent_data: boolean};
'insight.page_loads.screen_load': {has_ever_sent_data: boolean};
'insight.page_loads.screen_rendering': {has_ever_sent_data: boolean};
'insight.page_loads.vital': {has_ever_sent_data: boolean};
'insight.screen_load.spans.filter_by_device_class': {filter: string};
'insight.screen_load.spans.filter_by_operation': {filter: string};
Expand All @@ -54,6 +55,7 @@ export const insightEventMap: Record<InsightEventKey, string | null> = {
'insight.page_loads.queue': 'Insights: Queue Page Load',
'insight.page_loads.screen_load': 'Insights: Screen Load Page Load',
'insight.page_loads.vital': 'Insights: Vital Page Load',
'insight.page_loads.screen_rendering': 'Insights: Screen Rendering Page Load',
'insight.app_start.select_start_type': 'Insights: App Start - select app start type',
'insight.app_start.spans.filter_by_device_class':
'Insights: App Start - filter device class',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
MODULE_DATA_TYPES,
MODULE_DATA_TYPES_PLURAL,
MODULE_PRODUCT_DOC_LINKS,
MODULE_TITLES,
} from 'sentry/views/insights/settings';
import {ModuleName} from 'sentry/views/insights/types';
import PerformanceOnboarding from 'sentry/views/performance/onboarding';
Expand Down Expand Up @@ -458,4 +459,24 @@ const EMPTY_STATE_CONTENT: Record<TitleableModuleNames, EmptyStateContent> = {
imageSrc: screenLoadsPreviewImg,
supportedSdks: ['android', 'flutter', 'apple-ios', 'react-native'],
},
'screen-rendering': {
description: t(
'Screen Rendering shows you views within your application that are presenting slow or frozen interactions and how frequently these hiccups are occurring.'
),
heading: t('An app that loads quickly can still be terrible'),
imageSrc: screenLoadsPreviewImg, // TODO - replace with actual image
valuePropDescription: tct('With [moduleTitle]:', {
moduleTitle: MODULE_TITLES[ModuleName.SCREEN_RENDERING],
}),
valuePropPoints: [
tct('Compare [dataType] performance between releases.', {
dataType: MODULE_DATA_TYPES[ModuleName.SCREEN_RENDERING].toLowerCase(),
}),
t('Drill down to specific suspect operations.'),
tct('Correlate [dataType] performance with real-user metrics.', {
dataType: MODULE_DATA_TYPES[ModuleName.SCREEN_RENDERING].toLowerCase(),
}),
],
supportedSdks: ['android', 'flutter', 'apple-ios', 'react-native'],
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const modulePropertyMap: Record<
// Renamed resource to assets
[ModuleName.RESOURCE]: 'hasInsightsAssets',
[ModuleName.AI]: 'hasInsightsLlmMonitoring',
[ModuleName.SCREEN_RENDERING]: 'hasInsightsScreenLoad', // Screen rendering and screen loads share similar spans
};

/**
Expand Down
2 changes: 2 additions & 0 deletions static/app/views/insights/common/utils/moduleTitles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {MODULE_TITLE as HTTP_MODULE_TITLE} from 'sentry/views/insights/http/sett
import {MODULE_TITLE as AI_MODULE_TITLE} from 'sentry/views/insights/llmMonitoring/settings';
import {MODULE_TITLE as APP_STARTS_MODULE_TITLE} from 'sentry/views/insights/mobile/appStarts/settings';
import {MODULE_TITLE as SCREEN_LOADS_MODULE_TITLE} from 'sentry/views/insights/mobile/screenload/settings';
import {MODULE_TITLE as SCREEN_RENDERING_MODULE_TITLE} from 'sentry/views/insights/mobile/screenRendering/settings';
import {MODULE_TITLE as MOBILE_VITALS_MODULE_TITLE} from 'sentry/views/insights/mobile/screens/settings';
import {MODULE_TITLE as MOBILE_UI_MODULE_TITLE} from 'sentry/views/insights/mobile/ui/settings';
import {MODULE_TITLE as QUEUE_MODULE_TITLE} from 'sentry/views/insights/queues/settings';
Expand All @@ -23,5 +24,6 @@ export const MODULE_TITLES: Record<ModuleName, string> = {
[ModuleName.AI]: AI_MODULE_TITLE,
[ModuleName.MOBILE_UI]: MOBILE_UI_MODULE_TITLE,
[ModuleName.MOBILE_SCREENS]: MOBILE_VITALS_MODULE_TITLE,
[ModuleName.SCREEN_RENDERING]: SCREEN_RENDERING_MODULE_TITLE,
[ModuleName.OTHER]: '',
};
2 changes: 2 additions & 0 deletions static/app/views/insights/common/utils/useModuleURL.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {BASE_URL as HTTP_BASE_URL} from 'sentry/views/insights/http/settings';
import {BASE_URL as AI_BASE_URL} from 'sentry/views/insights/llmMonitoring/settings';
import {BASE_URL as APP_STARTS_BASE_URL} from 'sentry/views/insights/mobile/appStarts/settings';
import {BASE_URL as SCREEN_LOADS_BASE_URL} from 'sentry/views/insights/mobile/screenload/settings';
import {BASE_URL as SCREEN_RENDERING_BASE_URL} from 'sentry/views/insights/mobile/screenRendering/settings';
import {BASE_URL as MOBILE_SCREENS_BASE_URL} from 'sentry/views/insights/mobile/screens/settings';
import {BASE_URL as MOBILE_UI_BASE_URL} from 'sentry/views/insights/mobile/ui/settings';
import {DOMAIN_VIEW_BASE_URL} from 'sentry/views/insights/pages/settings';
Expand All @@ -31,6 +32,7 @@ export const MODULE_BASE_URLS: Record<ModuleName, string> = {
[ModuleName.AI]: AI_BASE_URL,
[ModuleName.MOBILE_UI]: MOBILE_UI_BASE_URL,
[ModuleName.MOBILE_SCREENS]: MOBILE_SCREENS_BASE_URL,
[ModuleName.SCREEN_RENDERING]: SCREEN_RENDERING_BASE_URL,
[ModuleName.OTHER]: '',
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ const LABEL_FOR_MODULE_NAME: {[key in ModuleName]: ReactNode} = {
other: t('Action'),
'mobile-ui': t('Action'),
'mobile-screens': t('Action'),
'screen-rendering': t('Action'),
ai: 'Action',
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ const LABEL_FOR_MODULE_NAME: {[key in ModuleName]: ReactNode} = {
resource: t('Resource'),
other: t('Domain'),
ai: t('Domain'),
'screen-rendering': t('Domain'),
'mobile-ui': t('Domain'),
'mobile-screens': t('Domain'),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export function SpanTimeCharts({
[ModuleName.AI]: [],
[ModuleName.MOBILE_UI]: [],
[ModuleName.MOBILE_SCREENS]: [],
[ModuleName.SCREEN_RENDERING]: [],
[ModuleName.OTHER]: [],
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import ScreensOverview from 'sentry/views/insights/mobile/screens/components/screensOverview';

export function ScreenRenderingContent() {
return <ScreensOverview />;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import styled from '@emotion/styled';

import ErrorBoundary from 'sentry/components/errorBoundary';
import * as Layout from 'sentry/components/layouts/thirds';
import {space} from 'sentry/styles/space';
import {PageAlert, PageAlertProvider} from 'sentry/utils/performance/contexts/pageAlert';
import {ModulePageFilterBar} from 'sentry/views/insights/common/components/modulePageFilterBar';
import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders';
import {ModulesOnboarding} from 'sentry/views/insights/common/components/modulesOnboarding';
import {ReleaseComparisonSelector} from 'sentry/views/insights/common/components/releaseSelector';
import useCrossPlatformProject from 'sentry/views/insights/mobile/common/queries/useCrossPlatformProject';
import {PlatformSelector} from 'sentry/views/insights/mobile/screenload/components/platformSelector';
import {ScreenRenderingContent} from 'sentry/views/insights/mobile/screenRendering/screenRenderingContent';
import {MODULE_TITLE} from 'sentry/views/insights/mobile/screenRendering/settings';
import {MobileHeader} from 'sentry/views/insights/pages/mobile/mobilePageHeader';
import {MODULE_FEATURE_MAP} from 'sentry/views/insights/settings';
import {ModuleName} from 'sentry/views/insights/types';

export function ScreenRenderingModule() {
const {isProjectCrossPlatform} = useCrossPlatformProject();

return (
<Layout.Page>
<PageAlertProvider>
<MobileHeader
module={ModuleName.SCREEN_RENDERING}
headerTitle={MODULE_TITLE}
headerActions={isProjectCrossPlatform && <PlatformSelector />}
/>

<Layout.Body>
<Layout.Main fullWidth>
<Container>
<ModulePageFilterBar
moduleName={ModuleName.SCREEN_LOAD}
extraFilters={<ReleaseComparisonSelector />}
/>
</Container>
<PageAlert />
<ErrorBoundary mini>
<ModulesOnboarding moduleName={ModuleName.SCREEN_RENDERING}>
<ScreenRenderingContent />
</ModulesOnboarding>
</ErrorBoundary>
</Layout.Main>
</Layout.Body>
</PageAlertProvider>
</Layout.Page>
);
}

function PageWithProviders() {
return (
<ModulePageProviders
moduleName="screen_load"
features={MODULE_FEATURE_MAP[ModuleName.SCREEN_RENDERING]}
analyticEventName="insight.page_loads.screen_load"
>
<ScreenRenderingModule />
</ModulePageProviders>
);
}

export default PageWithProviders;

const Container = styled('div')`
display: grid;
grid-template-rows: auto auto auto;
gap: ${space(2)};
margin-bottom: ${space(2)};

@media (min-width: ${p => p.theme.breakpoints.large}) {
grid-template-rows: auto;
grid-template-columns: auto 1fr auto;
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {Fragment} from 'react';

import * as Layout from 'sentry/components/layouts/thirds';
import {t} from 'sentry/locale';
import {useLocation} from 'sentry/utils/useLocation';
import * as ModuleLayout from 'sentry/views/insights/common/components/moduleLayout';
import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders';
import {
DATA_TYPE,
SUMMARY_PAGE_TITLE,
} from 'sentry/views/insights/mobile/screenRendering/settings';
import {ScreenSummaryContent} from 'sentry/views/insights/mobile/ui/views/screenSummaryPage';
import {MobileHeader} from 'sentry/views/insights/pages/mobile/mobilePageHeader';
import {MODULE_FEATURE_MAP} from 'sentry/views/insights/settings';
import {ModuleName} from 'sentry/views/insights/types';

function ScreenRenderingSummary() {
const location = useLocation();

const {transaction: transactionName} = location.query;
return (
<Fragment>
<MobileHeader
headerTitle={transactionName}
module={ModuleName.SCREEN_RENDERING}
breadcrumbs={[{label: SUMMARY_PAGE_TITLE}]}
/>
<Layout.Body>
<Layout.Main fullWidth>
<ModuleLayout.Layout>
<ModuleLayout.Full>
<ScreenSummaryContent />
</ModuleLayout.Full>
</ModuleLayout.Layout>
</Layout.Main>
</Layout.Body>
</Fragment>
);
}

function PageWithProviders() {
return (
<ModulePageProviders
moduleName={ModuleName.SCREEN_RENDERING}
pageTitle={`${DATA_TYPE} ${t('Summary')}`}
features={MODULE_FEATURE_MAP[ModuleName.SCREEN_RENDERING]}
>
<ScreenRenderingSummary />
</ModulePageProviders>
);
}

export default PageWithProviders;
17 changes: 17 additions & 0 deletions static/app/views/insights/mobile/screenRendering/settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {t} from 'sentry/locale';

export const MODULE_TITLE = t('Screen Rendering');
export const DATA_TYPE = t('Screen Render');
export const DATA_TYPE_PLURAL = t('Screen Renders');

export const CHART_HEIGHT = 160;

export const MODULE_DESCRIPTION = t('TODO');
export const MODULE_DOC_LINK = 'TODO';

export const BASE_URL = 'screen-rendering';
export const SUMMARY_PAGE_BASE_URL = 'details';

export const SUMMARY_PAGE_TITLE = t('Render Summary');

export const MODULE_FEATURES = ['insights-addon-modules', 'insights-domain-view'];
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import type EventView from 'sentry/utils/discover/eventView';
import {NumberContainer} from 'sentry/utils/discover/styles';
import normalizeUrl from 'sentry/utils/url/normalizeUrl';
import {useLocation} from 'sentry/utils/useLocation';
import useOrganization from 'sentry/utils/useOrganization';
import {OverflowEllipsisTextContainer} from 'sentry/views/insights/common/components/textAlign';
import {useModuleURL} from 'sentry/views/insights/common/utils/useModuleURL';
import {ScreensTable} from 'sentry/views/insights/mobile/common/components/tables/screensTable';
import {SUMMARY_PAGE_BASE_URL} from 'sentry/views/insights/mobile/screenRendering/settings';
import {isModuleEnabled} from 'sentry/views/insights/pages/utils';
import {ModuleName} from 'sentry/views/insights/types';

type Props = {
Expand All @@ -23,8 +26,13 @@ type Props = {

function ScreensOverviewTable({data, eventView, isLoading, pageLinks}: Props) {
const moduleURL = useModuleURL('mobile-screens');
const screenRenderingModuleUrl = useModuleURL(ModuleName.SCREEN_RENDERING);

const organization = useOrganization();
const location = useLocation();

const isMobileScreensEnabled = isModuleEnabled(ModuleName.MOBILE_SCREENS, organization);

const columnNameMap = {
transaction: t('Screen'),
[`count()`]: t('Screen Loads'),
Expand All @@ -43,13 +51,18 @@ function ScreensOverviewTable({data, eventView, isLoading, pageLinks}: Props) {
const field = String(column.key);

if (field === 'transaction') {
const link = normalizeUrl(
`${moduleURL}/details/?${qs.stringify({
...location.query,
project: row['project.id'],
transaction: row.transaction,
})}`
);
const queryString = qs.stringify({
...location.query,
project: row['project.id'],
transaction: row.transaction,
});

const link = isMobileScreensEnabled
? normalizeUrl(`${moduleURL}/details/?${queryString}`)
: normalizeUrl(
`${screenRenderingModuleUrl}/${SUMMARY_PAGE_BASE_URL}/?${queryString}`
);

return (
<Fragment>
<OverflowEllipsisTextContainer>
Expand Down
Loading
Loading