diff --git a/static/app/views/preprod/buildDetails/main/buildDetailsMainContent.tsx b/static/app/views/preprod/buildDetails/main/buildDetailsMainContent.tsx index 15e7dfcec47b4e..6db3d71b962e48 100644 --- a/static/app/views/preprod/buildDetails/main/buildDetailsMainContent.tsx +++ b/static/app/views/preprod/buildDetails/main/buildDetailsMainContent.tsx @@ -19,6 +19,7 @@ import {BuildDetailsMetricCards} from 'sentry/views/preprod/buildDetails/main/bu import {AppSizeInsights} from 'sentry/views/preprod/buildDetails/main/insights/appSizeInsights'; import {BuildError} from 'sentry/views/preprod/components/buildError'; import {BuildProcessing} from 'sentry/views/preprod/components/buildProcessing'; +import {openMissingDsymModal} from 'sentry/views/preprod/components/missingDsymModal'; import {AppSizeCategories} from 'sentry/views/preprod/components/visualizations/appSizeCategories'; import {AppSizeLegend} from 'sentry/views/preprod/components/visualizations/appSizeLegend'; import {AppSizeTreemap} from 'sentry/views/preprod/components/visualizations/appSizeTreemap'; @@ -234,13 +235,14 @@ export function BuildDetailsMainContent(props: BuildDetailsMainContentProps) { if (missingDsymBinaries && missingDsymBinaries.length > 0) { if (missingDsymBinaries?.length === 1) { return t( - 'Missing debug symbols for some binaries (%s). Those binaries will not have a detailed breakdown.', + 'Missing debug symbols for %s. This binary will not have a detailed breakdown.', missingDsymBinaries[0] ); } return t( - 'Missing debug symbols for some binaries (%s and others). Those binaries will not have a detailed breakdown.', - missingDsymBinaries[0] + 'Missing debug symbols for some binaries (%s and %s others). Those binaries will not have a detailed breakdown. Click to view details.', + missingDsymBinaries[0], + missingDsymBinaries.length - 1 ); } @@ -251,6 +253,12 @@ export function BuildDetailsMainContent(props: BuildDetailsMainContentProps) { return undefined; }; + const handleAlertClick = () => { + if (missingDsymBinaries && missingDsymBinaries.length > 0) { + openMissingDsymModal(missingDsymBinaries); + } + }; + // Filter data based on search query and categories const filteredRoot = filterTreemapElement( appSizeData.treemap.root, @@ -275,6 +283,11 @@ export function BuildDetailsMainContent(props: BuildDetailsMainContentProps) { searchQuery={searchQuery || ''} unfilteredRoot={appSizeData.treemap.root} alertMessage={getAlertMessage()} + onAlertClick={ + missingDsymBinaries && missingDsymBinaries.length > 1 + ? handleAlertClick + : undefined + } onSearchChange={value => setSearchQuery(value || undefined)} /> ) : ( @@ -290,6 +303,11 @@ export function BuildDetailsMainContent(props: BuildDetailsMainContentProps) { searchQuery={searchQuery || ''} unfilteredRoot={appSizeData.treemap.root} alertMessage={getAlertMessage()} + onAlertClick={ + missingDsymBinaries && missingDsymBinaries.length > 1 + ? handleAlertClick + : undefined + } onSearchChange={value => setSearchQuery(value || undefined)} /> ) : ( diff --git a/static/app/views/preprod/components/missingDsymModal.tsx b/static/app/views/preprod/components/missingDsymModal.tsx new file mode 100644 index 00000000000000..9e965ea25cd8c5 --- /dev/null +++ b/static/app/views/preprod/components/missingDsymModal.tsx @@ -0,0 +1,85 @@ +import {css} from '@emotion/react'; +import styled from '@emotion/styled'; + +import {Button} from '@sentry/scraps/button'; +import {Container, Flex, Stack} from '@sentry/scraps/layout'; +import {Heading, Text} from '@sentry/scraps/text'; + +import {openModal} from 'sentry/actionCreators/modal'; +import {IconClose} from 'sentry/icons/iconClose'; +import {t, tn} from 'sentry/locale'; +import {space} from 'sentry/styles/space'; + +interface MissingDsymModalProps { + binaries: string[]; + closeModal: () => void; +} + +function MissingDsymModal({binaries, closeModal}: MissingDsymModalProps) { + return ( + + + + {tn('Missing Debug Symbol', 'Missing Debug Symbols', binaries.length)} + + +