Skip to content

Commit

Permalink
feat(insights): create screen rendering module (#79192)
Browse files Browse the repository at this point in the history
This PR adds a screen rendering module under the domain view.
<img width="1258" alt="image"
src="https://github.com/user-attachments/assets/03ee8ea1-4df5-486e-b99d-a8bf7b074458">

This is a temporary change, the mobile screen module will require more
work, but we can extract the screen rendering section of it as its own
module in the meantime.

---------

Co-authored-by: Matt Quinn <matt.quinn@sentry.io>
  • Loading branch information
DominikB2014 and mjq authored Oct 18, 2024
1 parent eed024e commit c3c7968
Show file tree
Hide file tree
Showing 18 changed files with 254 additions and 10 deletions.
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 @@ -1748,6 +1749,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
21 changes: 21 additions & 0 deletions static/app/views/insights/common/components/modulesOnboarding.tsx
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

0 comments on commit c3c7968

Please sign in to comment.