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
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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
);
}

Expand All @@ -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,
Expand All @@ -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)}
/>
) : (
Expand All @@ -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)}
/>
) : (
Expand Down
85 changes: 85 additions & 0 deletions static/app/views/preprod/components/missingDsymModal.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Flex direction="column" gap="lg">
<Flex justify="center" align="center" width="100%" position="relative">
<Heading as="h2">
{tn('Missing Debug Symbol', 'Missing Debug Symbols', binaries.length)}
</Heading>
<Container
position="absolute"
style={{top: '50%', right: 0, transform: 'translateY(-50%)'}}
>
<Button
onClick={closeModal}
priority="transparent"
icon={<IconClose />}
size="sm"
aria-label={t('Close')}
/>
</Container>
</Flex>

<Text>
{t(
'The following binaries are missing debug symbols. Those binaries will not have a detailed breakdown in the size analysis.'
)}
</Text>

<BinaryList gap="xs">
{binaries.map(binary => (
<BinaryItem key={binary}>
<Text size="sm">{binary}</Text>
</BinaryItem>
))}
</BinaryList>
</Flex>
);
}

const BinaryList = styled(Stack)`
max-height: 400px;
overflow-y: auto;
padding: ${space(2)};
background: ${p => p.theme.backgroundSecondary};
border-radius: ${p => p.theme.borderRadius};
border: 1px solid ${p => p.theme.border};
`;

const BinaryItem = styled('div')`
padding: ${space(1)} ${space(1.5)};
background: ${p => p.theme.background};
border: 1px solid ${p => p.theme.border};

code {
font-family: ${p => p.theme.text.familyMono};
word-break: break-all;
}
`;

export function openMissingDsymModal(binaries: string[]) {
openModal(
({closeModal}) => <MissingDsymModal binaries={binaries} closeModal={closeModal} />,
{
modalCss: css`
max-width: 600px;
`,
}
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ interface AppSizeTreemapProps {
root: TreemapElement | null;
searchQuery: string;
alertMessage?: string;
onAlertClick?: () => void;
onSearchChange?: (query: string) => void;
unfilteredRoot?: TreemapElement;
}
Expand All @@ -32,11 +33,13 @@ function FullscreenModalContent({
unfilteredRoot,
initialSearch,
alertMessage,
onAlertClick,
onSearchChange,
}: {
initialSearch: string;
unfilteredRoot: TreemapElement;
alertMessage?: string;
onAlertClick?: () => void;
onSearchChange?: (query: string) => void;
}) {
const [localSearch, setLocalSearch] = useState(initialSearch);
Expand Down Expand Up @@ -76,6 +79,7 @@ function FullscreenModalContent({
root={filteredRoot}
searchQuery={localSearch}
alertMessage={alertMessage}
onAlertClick={onAlertClick}
/>
</Container>
</Flex>
Expand All @@ -84,7 +88,8 @@ function FullscreenModalContent({

export function AppSizeTreemap(props: AppSizeTreemapProps) {
const theme = useTheme();
const {root, searchQuery, unfilteredRoot, alertMessage, onSearchChange} = props;
const {root, searchQuery, unfilteredRoot, alertMessage, onAlertClick, onSearchChange} =
props;
const appSizeCategoryInfo = getAppSizeCategoryInfo(theme);
const renderingContext = useContext(ChartRenderingContext);
const isFullscreen = renderingContext?.isFullscreen ?? false;
Expand Down Expand Up @@ -323,7 +328,15 @@ export function AppSizeTreemap(props: AppSizeTreemapProps) {

return (
<Flex direction="column" gap="sm" height="100%" width="100%">
{alertMessage && <Alert type="warning">{alertMessage}</Alert>}
{alertMessage && (
<ClickableAlert
type="warning"
onClick={onAlertClick}
style={{cursor: onAlertClick ? 'pointer' : 'default'}}
>
{alertMessage}
</ClickableAlert>
)}
<Container
height="100%"
width="100%"
Expand Down Expand Up @@ -372,6 +385,7 @@ export function AppSizeTreemap(props: AppSizeTreemapProps) {
unfilteredRoot={unfilteredRoot}
initialSearch={searchQuery}
alertMessage={alertMessage}
onAlertClick={onAlertClick}
onSearchChange={onSearchChange}
/>
) : (
Expand All @@ -380,6 +394,7 @@ export function AppSizeTreemap(props: AppSizeTreemapProps) {
root={root}
searchQuery={searchQuery}
alertMessage={alertMessage}
onAlertClick={onAlertClick}
/>
</Container>
),
Expand All @@ -393,6 +408,12 @@ export function AppSizeTreemap(props: AppSizeTreemapProps) {
);
}

const ClickableAlert = styled(Alert)`
&:hover {
opacity: ${p => (p.onClick ? 0.9 : 1)};
}
`;

const ButtonContainer = styled(Flex)`
top: 0px;
right: 0;
Expand Down
Loading