diff --git a/static/app/components/modals/insightChartModal.tsx b/static/app/components/modals/insightChartModal.tsx index d0e0114709a9c3..4d27848ddb10d4 100644 --- a/static/app/components/modals/insightChartModal.tsx +++ b/static/app/components/modals/insightChartModal.tsx @@ -11,6 +11,7 @@ export type InsightChartModalOptions = { children: React.ReactNode; title: React.ReactNode; footer?: React.ReactNode; + height?: number; }; type Props = ModalRenderProps & InsightChartModalOptions; @@ -20,6 +21,7 @@ export default function InsightChartModal({ children, Footer, footer, + height = 300, }: Props) { return ( @@ -28,7 +30,7 @@ export default function InsightChartModal({

{title}

- + {children} diff --git a/static/app/views/preprod/buildDetails/main/buildDetailsMainContent.tsx b/static/app/views/preprod/buildDetails/main/buildDetailsMainContent.tsx index f54d54a0f797e8..0ffe9406b21d78 100644 --- a/static/app/views/preprod/buildDetails/main/buildDetailsMainContent.tsx +++ b/static/app/views/preprod/buildDetails/main/buildDetailsMainContent.tsx @@ -220,6 +220,8 @@ export function BuildDetailsMainContent(props: BuildDetailsMainContentProps) { setSearchQuery(value || undefined)} /> ) : ( No files found matching "{searchQuery}" @@ -229,7 +231,12 @@ export function BuildDetailsMainContent(props: BuildDetailsMainContentProps) { ); } else { visualizationContent = filteredTreemapData ? ( - + setSearchQuery(value || undefined)} + /> ) : ( No files found matching "{searchQuery}" ); diff --git a/static/app/views/preprod/components/visualizations/appSizeTreemap.tsx b/static/app/views/preprod/components/visualizations/appSizeTreemap.tsx index fe95d621456089..a6c21d7d239039 100644 --- a/static/app/views/preprod/components/visualizations/appSizeTreemap.tsx +++ b/static/app/views/preprod/components/visualizations/appSizeTreemap.tsx @@ -1,22 +1,86 @@ +import {useContext, useState} from 'react'; import {useTheme} from '@emotion/react'; import styled from '@emotion/styled'; import type {TreemapSeriesOption, VisualMapComponentOption} from 'echarts'; +import {openInsightChartModal} from 'sentry/actionCreators/modal'; import BaseChart, {type TooltipOption} from 'sentry/components/charts/baseChart'; +import {Button} from 'sentry/components/core/button'; +import {InputGroup} from 'sentry/components/core/input/inputGroup'; +import {Container, Flex} from 'sentry/components/core/layout'; import {Heading} from 'sentry/components/core/text'; +import {IconClose, IconExpand, IconSearch} from 'sentry/icons'; +import {t} from 'sentry/locale'; import {formatBytesBase10} from 'sentry/utils/bytes/formatBytesBase10'; +import {ChartRenderingContext} from 'sentry/views/insights/common/components/chart'; import {getAppSizeCategoryInfo} from 'sentry/views/preprod/components/visualizations/appSizeTheme'; import {TreemapType, type TreemapElement} from 'sentry/views/preprod/types/appSizeTypes'; +import {filterTreemapElement} from 'sentry/views/preprod/utils/treemapFiltering'; interface AppSizeTreemapProps { root: TreemapElement | null; searchQuery: string; + onSearchChange?: (query: string) => void; + unfilteredRoot?: TreemapElement; +} + +function FullscreenModalContent({ + unfilteredRoot, + initialSearch, + onSearchChange, +}: { + initialSearch: string; + unfilteredRoot: TreemapElement; + onSearchChange?: (query: string) => void; +}) { + const [localSearch, setLocalSearch] = useState(initialSearch); + const filteredRoot = filterTreemapElement(unfilteredRoot, localSearch, ''); + + const handleSearchChange = (value: string) => { + setLocalSearch(value); + onSearchChange?.(value); + }; + + return ( + + + + + + + handleSearchChange(e.target.value)} + /> + {localSearch && ( + + + + )} + + + + + + + ); } export function AppSizeTreemap(props: AppSizeTreemapProps) { const theme = useTheme(); - const {root} = props; + const {root, searchQuery, unfilteredRoot, onSearchChange} = props; const appSizeCategoryInfo = getAppSizeCategoryInfo(theme); + const renderingContext = useContext(ChartRenderingContext); + const isFullscreen = renderingContext?.isFullscreen ?? false; + const contextHeight = renderingContext?.height; function convertToEChartsData(element: TreemapElement): any { const categoryInfo = @@ -82,7 +146,7 @@ export function AppSizeTreemap(props: AppSizeTreemapProps) { // Empty state if (root === null) { return ( - + No files match your search:{' '} - + ); } @@ -109,8 +173,8 @@ export function AppSizeTreemap(props: AppSizeTreemapProps) { type: 'treemap', animationEasing: 'quarticOut', animationDuration: 300, - height: `calc(100% - 22px)`, - width: `100%`, + height: isFullscreen ? '100%' : `calc(100% - 22px)`, + width: '100%', top: '22px', breadcrumb: { show: true, @@ -224,21 +288,50 @@ export function AppSizeTreemap(props: AppSizeTreemapProps) { }; return ( - + + + {!isFullscreen && ( + +