diff --git a/static/app/views/insights/mobile/appStarts/components/tables/screensTable.tsx b/static/app/views/insights/mobile/appStarts/components/tables/screensTable.tsx index 5f3b0b6e2ac6e..2fbabde92a8d0 100644 --- a/static/app/views/insights/mobile/appStarts/components/tables/screensTable.tsx +++ b/static/app/views/insights/mobile/appStarts/components/tables/screensTable.tsx @@ -64,6 +64,13 @@ export function AppStartScreens({data, eventView, isLoading, pageLinks}: Props) 'count_starts(measurements.app_start_warm)': t('Warm Start Count'), }; + const columnTooltipMap = { + [`avg_compare(measurements.app_start_cold,release,${primaryRelease},${secondaryRelease})`]: + t('Average Cold Start difference'), + [`avg_compare(measurements.app_start_warm,release,${primaryRelease},${secondaryRelease})`]: + t('Average Warm Start difference'), + }; + function renderBodyCell(column, row): React.ReactNode { if (!data) { return null; @@ -121,6 +128,7 @@ export function AppStartScreens({data, eventView, isLoading, pageLinks}: Props) return ( { columnNameMap={{ transaction: 'Screen', }} + columnTooltipMap={{}} columnOrder={['transaction']} data={{ data: [{id: '1', transaction: 'Screen 1'}], @@ -56,6 +57,7 @@ describe('ScreensTable', () => { columnNameMap={{ transaction: 'Screen', }} + columnTooltipMap={{}} columnOrder={['transaction', 'non-custom']} data={{ data: [ @@ -82,4 +84,35 @@ describe('ScreensTable', () => { expect(screen.getByText('Custom rendered Screen 1')).toBeInTheDocument(); expect(screen.getByText('non customized value')).toBeInTheDocument(); }); + + it('renders column header tooltips', async () => { + render( + + ); + + const columnHeader = screen.getByText('Screen Column'); + await userEvent.hover(columnHeader); + + expect(await screen.findByText('Screen Column Tooltip')).toBeInTheDocument(); + }); }); diff --git a/static/app/views/insights/mobile/common/components/tables/screensTable.tsx b/static/app/views/insights/mobile/common/components/tables/screensTable.tsx index 5d8607085313b..bba1999085b9e 100644 --- a/static/app/views/insights/mobile/common/components/tables/screensTable.tsx +++ b/static/app/views/insights/mobile/common/components/tables/screensTable.tsx @@ -1,4 +1,5 @@ import {Fragment} from 'react'; +import styled from '@emotion/styled'; import type { GridColumn, @@ -8,6 +9,7 @@ import type { import GridEditable, {COL_WIDTH_UNDEFINED} from 'sentry/components/gridEditable'; import SortLink from 'sentry/components/gridEditable/sortLink'; import Pagination from 'sentry/components/pagination'; +import {Tooltip} from 'sentry/components/tooltip'; import {defined} from 'sentry/utils'; import {trackAnalytics} from 'sentry/utils/analytics'; import type {TableData, TableDataRow} from 'sentry/utils/discover/discoverQuery'; @@ -23,6 +25,7 @@ import type {ModuleName} from 'sentry/views/insights/types'; type Props = { columnNameMap: Record; columnOrder: string[]; + columnTooltipMap: Record | undefined; data: TableData | undefined; defaultSort: GridColumnSortBy[]; eventView: EventView; @@ -42,6 +45,7 @@ export function ScreensTable({ pageLinks, columnNameMap, columnOrder, + columnTooltipMap, defaultSort, customBodyCellRenderer, moduleName, @@ -116,6 +120,21 @@ export function ScreensTable({ generateSortLink={generateSortLink} /> ); + + function columnWithTooltip(tooltipTitle: string) { + return ( + + {tooltipTitle}}> + {sortLink} + + + ); + } + + const tooltip = columnTooltipMap ? columnTooltipMap[column.key] : undefined; + if (tooltip) { + return columnWithTooltip(tooltip); + } return sortLink; } @@ -152,3 +171,15 @@ export function ScreensTable({ ); } + +const Alignment = styled('span')<{align: string}>` + display: block; + margin: auto; + text-align: ${props => props.align}; + width: 100%; +`; + +const StyledTooltip = styled(Tooltip)` + top: 1px; + position: relative; +`; diff --git a/static/app/views/insights/mobile/ui/components/tables/spanOperationTable.spec.tsx b/static/app/views/insights/mobile/ui/components/tables/spanOperationTable.spec.tsx index 0127bdf0c0bd6..cb42a8d8e7b0b 100644 --- a/static/app/views/insights/mobile/ui/components/tables/spanOperationTable.spec.tsx +++ b/static/app/views/insights/mobile/ui/components/tables/spanOperationTable.spec.tsx @@ -63,10 +63,10 @@ describe('SpanOperationTable', () => { 'span.op', 'span.group', 'span.description', - 'avg_if(mobile.slow_frames,release,foo)', - 'avg_if(mobile.slow_frames,release,bar)', - 'avg_if(mobile.frozen_frames,release,foo)', - 'avg_if(mobile.frozen_frames,release,bar)', + 'division_if(mobile.slow_frames,mobile.total_frames,release,foo)', + 'division_if(mobile.slow_frames,mobile.total_frames,release,bar)', + 'division_if(mobile.frozen_frames,mobile.total_frames,release,foo)', + 'division_if(mobile.frozen_frames,mobile.total_frames,release,bar)', 'avg_if(mobile.frames_delay,release,foo)', 'avg_if(mobile.frames_delay,release,bar)', 'avg_compare(mobile.frames_delay,release,foo,bar)', diff --git a/static/app/views/insights/mobile/ui/components/tables/spanOperationTable.tsx b/static/app/views/insights/mobile/ui/components/tables/spanOperationTable.tsx index 4ea2d297d0366..b5653d9f33cd3 100644 --- a/static/app/views/insights/mobile/ui/components/tables/spanOperationTable.tsx +++ b/static/app/views/insights/mobile/ui/components/tables/spanOperationTable.tsx @@ -69,10 +69,10 @@ export function SpanOperationTable({ SPAN_OP, SPAN_GROUP, SPAN_DESCRIPTION, - `avg_if(mobile.slow_frames,release,${primaryRelease})`, - `avg_if(mobile.slow_frames,release,${secondaryRelease})`, - `avg_if(mobile.frozen_frames,release,${primaryRelease})`, - `avg_if(mobile.frozen_frames,release,${secondaryRelease})`, + `division_if(mobile.slow_frames,mobile.total_frames,release,${primaryRelease})`, + `division_if(mobile.slow_frames,mobile.total_frames,release,${secondaryRelease})`, + `division_if(mobile.frozen_frames,mobile.total_frames,release,${primaryRelease})`, + `division_if(mobile.frozen_frames,mobile.total_frames,release,${secondaryRelease})`, `avg_if(mobile.frames_delay,release,${primaryRelease})`, `avg_if(mobile.frames_delay,release,${secondaryRelease})`, `avg_compare(mobile.frames_delay,release,${primaryRelease},${secondaryRelease})`, @@ -97,22 +97,16 @@ export function SpanOperationTable({ const columnNameMap = { [SPAN_OP]: t('Operation'), [SPAN_DESCRIPTION]: t('Span Description'), - [`avg_if(mobile.slow_frames,release,${primaryRelease})`]: t( + [`division_if(mobile.slow_frames,mobile.total_frames,release,${primaryRelease})`]: t( 'Slow (%s)', PRIMARY_RELEASE_ALIAS ), - [`avg_if(mobile.slow_frames,release,${secondaryRelease})`]: t( - 'Slow (%s)', - SECONDARY_RELEASE_ALIAS - ), - [`avg_if(mobile.frozen_frames,release,${primaryRelease})`]: t( - 'Frozen (%s)', - PRIMARY_RELEASE_ALIAS - ), - [`avg_if(mobile.frozen_frames,release,${secondaryRelease})`]: t( - 'Frozen (%s)', - SECONDARY_RELEASE_ALIAS - ), + [`division_if(mobile.slow_frames,mobile.total_frames,release,${secondaryRelease})`]: + t('Slow (%s)', SECONDARY_RELEASE_ALIAS), + [`division_if(mobile.frozen_frames,mobile.total_frames,release,${primaryRelease})`]: + t('Frozen (%s)', PRIMARY_RELEASE_ALIAS), + [`division_if(mobile.frozen_frames,mobile.total_frames,release,${secondaryRelease})`]: + t('Frozen (%s)', SECONDARY_RELEASE_ALIAS), [`avg_if(mobile.frames_delay,release,${primaryRelease})`]: t( 'Delay (%s)', PRIMARY_RELEASE_ALIAS @@ -125,6 +119,28 @@ export function SpanOperationTable({ t('Change'), }; + const columnTooltipMap = { + [`division_if(mobile.slow_frames,mobile.total_frames,release,${primaryRelease})`]: t( + 'The number of slow frames divided by total frames (%s)', + PRIMARY_RELEASE_ALIAS + ), + [`division_if(mobile.slow_frames,mobile.total_frames,release,${secondaryRelease})`]: + t( + 'The number of slow frames divided by total frames (%s)', + SECONDARY_RELEASE_ALIAS + ), + [`division_if(mobile.frozen_frames,mobile.total_frames,release,${primaryRelease})`]: + t( + 'The number of frozen frames divided by total frames (%s)', + PRIMARY_RELEASE_ALIAS + ), + [`division_if(mobile.frozen_frames,mobile.total_frames,release,${secondaryRelease})`]: + t( + 'The number of frozen frames divided by total frames (%s)', + SECONDARY_RELEASE_ALIAS + ), + }; + function renderBodyCell(column, row) { if (column.key === SPAN_DESCRIPTION) { const label = row[SpanMetricsField.SPAN_DESCRIPTION]; @@ -163,6 +179,7 @@ export function SpanOperationTable({ return ( { field: [ 'project.id', 'transaction', - 'avg_if(mobile.slow_frames,release,com.example.vu.android@2.10.5)', - 'avg_if(mobile.slow_frames,release,com.example.vu.android@2.10.3+42)', - 'avg_if(mobile.frozen_frames,release,com.example.vu.android@2.10.5)', - 'avg_if(mobile.frozen_frames,release,com.example.vu.android@2.10.3+42)', + 'division_if(mobile.slow_frames,mobile.total_frames,release,com.example.vu.android@2.10.5)', + 'division_if(mobile.slow_frames,mobile.total_frames,release,com.example.vu.android@2.10.3+42)', + 'division_if(mobile.frozen_frames,mobile.total_frames,release,com.example.vu.android@2.10.5)', + 'division_if(mobile.frozen_frames,mobile.total_frames,release,com.example.vu.android@2.10.3+42)', 'avg_if(mobile.frames_delay,release,com.example.vu.android@2.10.5)', 'avg_if(mobile.frames_delay,release,com.example.vu.android@2.10.3+42)', 'avg_compare(mobile.frames_delay,release,com.example.vu.android@2.10.5,com.example.vu.android@2.10.3+42)', diff --git a/static/app/views/insights/mobile/ui/components/uiScreens.tsx b/static/app/views/insights/mobile/ui/components/uiScreens.tsx index ae0efa52a1fb3..9bc0fe837c359 100644 --- a/static/app/views/insights/mobile/ui/components/uiScreens.tsx +++ b/static/app/views/insights/mobile/ui/components/uiScreens.tsx @@ -66,10 +66,10 @@ export function UIScreens() { fields: [ SpanMetricsField.PROJECT_ID, 'transaction', - `avg_if(mobile.slow_frames,release,${primaryRelease})`, - `avg_if(mobile.slow_frames,release,${secondaryRelease})`, - `avg_if(mobile.frozen_frames,release,${primaryRelease})`, - `avg_if(mobile.frozen_frames,release,${secondaryRelease})`, + `division_if(mobile.slow_frames,mobile.total_frames,release,${primaryRelease})`, + `division_if(mobile.slow_frames,mobile.total_frames,release,${secondaryRelease})`, + `division_if(mobile.frozen_frames,mobile.total_frames,release,${primaryRelease})`, + `division_if(mobile.frozen_frames,mobile.total_frames,release,${secondaryRelease})`, `avg_if(mobile.frames_delay,release,${primaryRelease})`, `avg_if(mobile.frames_delay,release,${secondaryRelease})`, `avg_compare(mobile.frames_delay,release,${primaryRelease},${secondaryRelease})`,