From 6d285e6eb63fd3092bc4486700a2b6f4b05cfd7d Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Fri, 20 Dec 2024 16:36:50 -0500 Subject: [PATCH 01/37] Add panel header component --- .../sampleDrawerHeaderTransaction.spec.tsx | 50 +++++++++++++++++ .../sampleDrawerHeaderTransaction.tsx | 55 +++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 static/app/views/insights/common/components/sampleDrawerHeaderTransaction.spec.tsx create mode 100644 static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx diff --git a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.spec.tsx b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.spec.tsx new file mode 100644 index 00000000000000..fd062a11554135 --- /dev/null +++ b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.spec.tsx @@ -0,0 +1,50 @@ +import {ProjectFixture} from 'sentry-fixture/project'; + +import {render, screen} from 'sentry-test/reactTestingLibrary'; + +import {SampleDrawerHeaderTransaction} from './sampleDrawerHeader'; + +describe('SampleDrawerHeaderTransaction', () => { + it('Links to the transaction summary page', () => { + const project = ProjectFixture(); + + render(); + + const $link = screen.getByRole('link'); + expect($link).toHaveAccessibleName('/issues'); + expect($link).toHaveAttribute( + 'href', + '/organizations/org-slug/performance/summary?project=project-slug&transaction=%2Fissues' + ); + }); + + it('Shows transaction method', () => { + const project = ProjectFixture(); + + render( + + ); + + const $link = screen.getByRole('link'); + expect($link).toHaveAccessibleName('GET /issues'); + }); + + it('Strips duplicate transaction method', () => { + const project = ProjectFixture(); + + render( + + ); + + const $link = screen.getByRole('link'); + expect($link).toHaveAccessibleName('GET /issues'); + }); +}); diff --git a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx new file mode 100644 index 00000000000000..bcbfaeb24c6670 --- /dev/null +++ b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx @@ -0,0 +1,55 @@ +import {Link} from 'react-router-dom'; +import styled from '@emotion/styled'; +import * as qs from 'query-string'; + +import ProjectAvatar from 'sentry/components/avatar/projectAvatar'; +import {space} from 'sentry/styles/space'; +import type {Project} from 'sentry/types/project'; +import useOrganization from 'sentry/utils/useOrganization'; +import {getTransactionSummaryBaseUrl} from 'sentry/views/performance/transactionSummary/utils'; + +import {useDomainViewFilters} from '../../pages/useFilters'; + +interface SampleDrawerHeaderProps { + project: Project; + transaction: string; + transactionMethod?: string; +} + +export function SampleDrawerHeaderTransaction(props: SampleDrawerHeaderProps) { + const organization = useOrganization(); + + const {project, transaction, transactionMethod} = props; + const {view} = useDomainViewFilters(); + + return ( + + + + + {transaction && transactionMethod && !transaction.startsWith(transactionMethod) + ? `${transactionMethod} ${transaction}` + : transaction} + + + ); +} + +const Bar = styled('div')` + display: flex; + gap: ${space(1)}; +`; From 55f66d1d96452280d28cfd0d73d5c172a947b0f0 Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Fri, 20 Dec 2024 16:46:11 -0500 Subject: [PATCH 02/37] Add body component --- .../common/components/sampleDrawerBody.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 static/app/views/insights/common/components/sampleDrawerBody.tsx diff --git a/static/app/views/insights/common/components/sampleDrawerBody.tsx b/static/app/views/insights/common/components/sampleDrawerBody.tsx new file mode 100644 index 00000000000000..ad48a32c56978a --- /dev/null +++ b/static/app/views/insights/common/components/sampleDrawerBody.tsx @@ -0,0 +1,15 @@ +import styled from '@emotion/styled'; + +import {DrawerBody} from 'sentry/components/globalDrawer/components'; +import {space} from 'sentry/styles/space'; + +export const SampleDrawerBody = styled(DrawerBody)` + overflow: auto; + overscroll-behavior: contain; + /* Move the scrollbar to the left edge */ + scroll-margin: 0 ${space(2)}; + direction: rtl; + * { + direction: ltr; + } +`; From 239b95d0a8d13f81534d492d4a77a891d73b378c Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Fri, 20 Dec 2024 16:54:17 -0500 Subject: [PATCH 03/37] Truncate the link --- .../common/components/sampleDrawerHeaderTransaction.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx index bcbfaeb24c6670..200154efc290f2 100644 --- a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx +++ b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx @@ -32,7 +32,7 @@ export function SampleDrawerHeaderTransaction(props: SampleDrawerHeaderProps) { tooltip={project.slug} /> - + ); } const Bar = styled('div')` display: flex; + align-items: center; gap: ${space(1)}; `; + +const TruncatedLink = styled(Link)` + ${p => p.theme.overflowEllipsis} +`; From bac440b6a17b4279df115685bf722942ae5261de Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Fri, 20 Dec 2024 16:56:18 -0500 Subject: [PATCH 04/37] Use new drawer in HTTP samples panel --- .../http/components/httpSamplesPanel.tsx | 100 +++--------------- .../http/views/httpDomainSummaryPage.tsx | 46 +++++++- 2 files changed, 60 insertions(+), 86 deletions(-) diff --git a/static/app/views/insights/http/components/httpSamplesPanel.tsx b/static/app/views/insights/http/components/httpSamplesPanel.tsx index c8aae218f61a92..28f967d576ee20 100644 --- a/static/app/views/insights/http/components/httpSamplesPanel.tsx +++ b/static/app/views/insights/http/components/httpSamplesPanel.tsx @@ -1,11 +1,9 @@ -import {Fragment, useCallback} from 'react'; +import {Fragment} from 'react'; import styled from '@emotion/styled'; -import * as qs from 'query-string'; -import ProjectAvatar from 'sentry/components/avatar/projectAvatar'; import {Button} from 'sentry/components/button'; import {CompactSelect} from 'sentry/components/compactSelect'; -import Link from 'sentry/components/links/link'; +import {DrawerHeader} from 'sentry/components/globalDrawer/components'; import {SpanSearchQueryBuilder} from 'sentry/components/performance/spanSearchQueryBuilder'; import {SegmentedControl} from 'sentry/components/segmentedControl'; import {t} from 'sentry/locale'; @@ -26,7 +24,6 @@ import useOrganization from 'sentry/utils/useOrganization'; import usePageFilters from 'sentry/utils/usePageFilters'; import useProjects from 'sentry/utils/useProjects'; import {computeAxisMax} from 'sentry/views/insights/common/components/chart'; -import DetailPanel from 'sentry/views/insights/common/components/detailPanel'; import {MetricReadout} from 'sentry/views/insights/common/components/metricReadout'; import * as ModuleLayout from 'sentry/views/insights/common/components/moduleLayout'; import {ReadoutRibbon} from 'sentry/views/insights/common/components/ribbon'; @@ -54,7 +51,6 @@ import {BASE_FILTERS} from 'sentry/views/insights/http/settings'; import decodePanel from 'sentry/views/insights/http/utils/queryParameterDecoders/panel'; import decodeResponseCodeClass from 'sentry/views/insights/http/utils/queryParameterDecoders/responseCodeClass'; import {useDebouncedState} from 'sentry/views/insights/http/utils/useDebouncedState'; -import {useDomainViewFilters} from 'sentry/views/insights/pages/useFilters'; import { ModuleName, SpanFunction, @@ -63,7 +59,9 @@ import { type SpanMetricsQueryFilters, } from 'sentry/views/insights/types'; import {TraceViewSources} from 'sentry/views/performance/newTraceDetails/traceHeader/breadcrumbs'; -import {getTransactionSummaryBaseUrl} from 'sentry/views/performance/transactionSummary/utils'; + +import {SampleDrawerBody} from '../../common/components/sampleDrawerBody'; +import {SampleDrawerHeaderTransaction} from '../../common/components/sampleDrawerHeaderTransaction'; export function HTTPSamplesPanel() { const navigate = useNavigate(); @@ -83,7 +81,6 @@ export function HTTPSamplesPanel() { }); const organization = useOrganization(); - const {view} = useDomainViewFilters(); const {projects} = useProjects(); const {selection} = usePageFilters(); @@ -293,60 +290,20 @@ export function HTTPSamplesPanel() { } }; - const handleClose = () => { - navigate({ - pathname: location.pathname, - query: { - ...location.query, - transaction: undefined, - transactionMethod: undefined, - }, - }); - }; - - const handleOpen = useCallback(() => { - if (query.transaction) { - trackAnalytics('performance_views.sample_spans.opened', { - organization, - source: ModuleName.HTTP, - }); - } - }, [organization, query.transaction]); - return ( - + + {project && ( + + )} + + + - - - {project && ( - - )} - - <Link - to={`${getTransactionSummaryBaseUrl(organization.slug, view)}?${qs.stringify( - { - project: query.project, - transaction: query.transaction, - } - )}`} - > - {query.transaction && - query.transactionMethod && - !query.transaction.startsWith(query.transactionMethod) - ? `${query.transactionMethod} ${query.transaction}` - : query.transaction} - </Link> - - - - )} - + ); } @@ -570,10 +527,6 @@ const SPAN_SAMPLES_SORT = { kind: 'desc' as const, }; -const SpanSummaryProjectAvatar = styled(ProjectAvatar)` - padding-right: ${space(1)}; -`; - const HTTP_RESPONSE_CODE_CLASS_OPTIONS = [ { value: '', @@ -597,25 +550,6 @@ const HTTP_RESPONSE_CODE_CLASS_OPTIONS = [ }, ]; -// TODO - copy of static/app/views/starfish/views/spanSummaryPage/sampleList/index.tsx -const HeaderContainer = styled('div')` - display: grid; - grid-template-rows: auto auto auto; - align-items: center; - - @media (min-width: ${p => p.theme.breakpoints.small}) { - grid-template-rows: auto; - grid-template-columns: auto 1fr; - } -`; - -const Title = styled('h4')` - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - margin: 0; -`; - const PanelControls = styled('div')` display: flex; justify-content: space-between; diff --git a/static/app/views/insights/http/views/httpDomainSummaryPage.tsx b/static/app/views/insights/http/views/httpDomainSummaryPage.tsx index 33ec1acbb8c306..3ad20ab1dd5914 100644 --- a/static/app/views/insights/http/views/httpDomainSummaryPage.tsx +++ b/static/app/views/insights/http/views/httpDomainSummaryPage.tsx @@ -1,10 +1,12 @@ -import React, {Fragment} from 'react'; +import React, {Fragment, useCallback, useEffect} from 'react'; import Alert from 'sentry/components/alert'; import ProjectAvatar from 'sentry/components/avatar/projectAvatar'; +import useDrawer from 'sentry/components/globalDrawer'; import * as Layout from 'sentry/components/layouts/thirds'; import ExternalLink from 'sentry/components/links/externalLink'; import {t, tct} from 'sentry/locale'; +import {trackAnalytics} from 'sentry/utils/analytics'; import {DurationUnit, RateUnit} from 'sentry/utils/discover/fields'; import {decodeList, decodeScalar, decodeSorts} from 'sentry/utils/queryString'; import { @@ -14,6 +16,8 @@ import { } from 'sentry/utils/tokenizeSearch'; import useLocationQuery from 'sentry/utils/url/useLocationQuery'; import {useLocation} from 'sentry/utils/useLocation'; +import {useNavigate} from 'sentry/utils/useNavigate'; +import useOrganization from 'sentry/utils/useOrganization'; import useProjects from 'sentry/utils/useProjects'; import {useSynchronizeCharts} from 'sentry/views/insights/common/components/chart'; import {HeaderContainer} from 'sentry/views/insights/common/components/headerContainer'; @@ -64,6 +68,7 @@ type Query = { export function HTTPDomainSummaryPage() { const location = useLocation(); + const organization = useOrganization(); const {projects} = useProjects(); const {view} = useDomainViewFilters(); @@ -75,15 +80,52 @@ export function HTTPDomainSummaryPage() { const { domain, project: projectId, + transaction, + transactionMethod, 'user.geo.subregion': subregions, } = useLocationQuery({ fields: { project: decodeScalar, domain: decodeScalar, [SpanMetricsField.USER_GEO_SUBREGION]: decodeList, + transaction: decodeScalar, + transactionMethod: decodeScalar, }, }); + const {openDrawer} = useDrawer(); + const navigate = useNavigate(); + + const openSamplesPanel = useCallback(() => { + openDrawer(() => , { + ariaLabel: t('Samples'), + onClose: () => { + navigate({ + query: { + ...location.query, + transaction: undefined, + transactionMethod: undefined, + }, + }); + }, + transitionProps: {stiffness: 1000}, + }); + }, [openDrawer, navigate, location.query]); + + useEffect(() => { + const detailKey = transaction + ? [domain, transactionMethod, transaction].filter(Boolean).join(':') + : undefined; + + if (detailKey) { + trackAnalytics('performance_views.sample_spans.opened', { + organization, + source: ModuleName.HTTP, + }); + openSamplesPanel(); + } + }); + const project = projects.find(p => projectId === p.id); const filters: SpanMetricsQueryFilters = { ...BASE_FILTERS, @@ -335,8 +377,6 @@ export function HTTPDomainSummaryPage() { - - ); } From 343467683d431d6f2528069c97f71db3df4fc609 Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Fri, 20 Dec 2024 18:23:20 -0500 Subject: [PATCH 05/37] Extract drawer hook --- .../common/utils/useSamplesDrawer.tsx | 47 +++++++++++++++++++ .../http/views/httpDomainSummaryPage.tsx | 45 ++++-------------- 2 files changed, 56 insertions(+), 36 deletions(-) create mode 100644 static/app/views/insights/common/utils/useSamplesDrawer.tsx diff --git a/static/app/views/insights/common/utils/useSamplesDrawer.tsx b/static/app/views/insights/common/utils/useSamplesDrawer.tsx new file mode 100644 index 00000000000000..381ab1c839d1e5 --- /dev/null +++ b/static/app/views/insights/common/utils/useSamplesDrawer.tsx @@ -0,0 +1,47 @@ +import {useCallback} from 'react'; + +import useDrawer from 'sentry/components/globalDrawer'; +import {t} from 'sentry/locale'; +import {trackAnalytics} from 'sentry/utils/analytics'; +import {useLocation} from 'sentry/utils/useLocation'; +import {useNavigate} from 'sentry/utils/useNavigate'; +import useOrganization from 'sentry/utils/useOrganization'; + +import type {ModuleName} from '../../types'; + +interface UseSamplesDrawerProps { + Component: React.FunctionComponent; + moduleName: ModuleName; +} + +export function useSamplesDrawer({Component, moduleName}: UseSamplesDrawerProps) { + const organization = useOrganization(); + const {openDrawer} = useDrawer(); + const navigate = useNavigate(); + const location = useLocation(); + + const onClose = useCallback(() => { + navigate({ + query: { + ...location.query, + transaction: undefined, + transactionMethod: undefined, + }, + }); + }, [navigate, location.query]); + + const openSamplesDrawer = useCallback(() => { + trackAnalytics('performance_views.sample_spans.opened', { + organization, + source: moduleName, + }); + + openDrawer(() => , { + ariaLabel: t('Samples'), + onClose, + transitionProps: {stiffness: 1000}, + }); + }, [openDrawer, onClose, Component, organization, moduleName]); + + return {openSamplesDrawer}; +} diff --git a/static/app/views/insights/http/views/httpDomainSummaryPage.tsx b/static/app/views/insights/http/views/httpDomainSummaryPage.tsx index 3ad20ab1dd5914..00f42087a0bbcb 100644 --- a/static/app/views/insights/http/views/httpDomainSummaryPage.tsx +++ b/static/app/views/insights/http/views/httpDomainSummaryPage.tsx @@ -1,12 +1,10 @@ -import React, {Fragment, useCallback, useEffect} from 'react'; +import React, {Fragment, useEffect} from 'react'; import Alert from 'sentry/components/alert'; import ProjectAvatar from 'sentry/components/avatar/projectAvatar'; -import useDrawer from 'sentry/components/globalDrawer'; import * as Layout from 'sentry/components/layouts/thirds'; import ExternalLink from 'sentry/components/links/externalLink'; import {t, tct} from 'sentry/locale'; -import {trackAnalytics} from 'sentry/utils/analytics'; import {DurationUnit, RateUnit} from 'sentry/utils/discover/fields'; import {decodeList, decodeScalar, decodeSorts} from 'sentry/utils/queryString'; import { @@ -16,8 +14,6 @@ import { } from 'sentry/utils/tokenizeSearch'; import useLocationQuery from 'sentry/utils/url/useLocationQuery'; import {useLocation} from 'sentry/utils/useLocation'; -import {useNavigate} from 'sentry/utils/useNavigate'; -import useOrganization from 'sentry/utils/useOrganization'; import useProjects from 'sentry/utils/useProjects'; import {useSynchronizeCharts} from 'sentry/views/insights/common/components/chart'; import {HeaderContainer} from 'sentry/views/insights/common/components/headerContainer'; @@ -61,6 +57,8 @@ import {useDomainViewFilters} from 'sentry/views/insights/pages/useFilters'; import type {SpanMetricsQueryFilters} from 'sentry/views/insights/types'; import {ModuleName, SpanFunction, SpanMetricsField} from 'sentry/views/insights/types'; +import {useSamplesDrawer} from '../../common/utils/useSamplesDrawer'; + type Query = { aggregate?: string; domain?: string; @@ -68,7 +66,6 @@ type Query = { export function HTTPDomainSummaryPage() { const location = useLocation(); - const organization = useOrganization(); const {projects} = useProjects(); const {view} = useDomainViewFilters(); @@ -81,7 +78,6 @@ export function HTTPDomainSummaryPage() { domain, project: projectId, transaction, - transactionMethod, 'user.geo.subregion': subregions, } = useLocationQuery({ fields: { @@ -89,40 +85,17 @@ export function HTTPDomainSummaryPage() { domain: decodeScalar, [SpanMetricsField.USER_GEO_SUBREGION]: decodeList, transaction: decodeScalar, - transactionMethod: decodeScalar, }, }); - const {openDrawer} = useDrawer(); - const navigate = useNavigate(); - - const openSamplesPanel = useCallback(() => { - openDrawer(() => , { - ariaLabel: t('Samples'), - onClose: () => { - navigate({ - query: { - ...location.query, - transaction: undefined, - transactionMethod: undefined, - }, - }); - }, - transitionProps: {stiffness: 1000}, - }); - }, [openDrawer, navigate, location.query]); + const {openSamplesDrawer} = useSamplesDrawer({ + Component: HTTPSamplesPanel, + moduleName: ModuleName.HTTP, + }); useEffect(() => { - const detailKey = transaction - ? [domain, transactionMethod, transaction].filter(Boolean).join(':') - : undefined; - - if (detailKey) { - trackAnalytics('performance_views.sample_spans.opened', { - organization, - source: ModuleName.HTTP, - }); - openSamplesPanel(); + if (transaction) { + openSamplesDrawer(); } }); From bd92a4c736c3ab92f3752bfdbd1b79b3a4e7a57c Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Fri, 20 Dec 2024 18:31:07 -0500 Subject: [PATCH 06/37] Use new drawer in Caches --- .../insights/cache/components/samplePanel.tsx | 100 +++--------------- .../insights/cache/views/cacheLandingPage.tsx | 21 +++- 2 files changed, 36 insertions(+), 85 deletions(-) diff --git a/static/app/views/insights/cache/components/samplePanel.tsx b/static/app/views/insights/cache/components/samplePanel.tsx index cccee628a406c5..d404f35033b49f 100644 --- a/static/app/views/insights/cache/components/samplePanel.tsx +++ b/static/app/views/insights/cache/components/samplePanel.tsx @@ -1,21 +1,16 @@ -import {Fragment, useCallback} from 'react'; -import styled from '@emotion/styled'; +import {Fragment} from 'react'; import keyBy from 'lodash/keyBy'; -import * as qs from 'query-string'; -import ProjectAvatar from 'sentry/components/avatar/projectAvatar'; import {Button} from 'sentry/components/button'; import {CompactSelect} from 'sentry/components/compactSelect'; -import Link from 'sentry/components/links/link'; +import {DrawerHeader} from 'sentry/components/globalDrawer/components'; import {SpanSearchQueryBuilder} from 'sentry/components/performance/spanSearchQueryBuilder'; import {t} from 'sentry/locale'; -import {space} from 'sentry/styles/space'; import {trackAnalytics} from 'sentry/utils/analytics'; import {DurationUnit, RateUnit, SizeUnit} from 'sentry/utils/discover/fields'; import {PageAlertProvider} from 'sentry/utils/performance/contexts/pageAlert'; import {decodeScalar} from 'sentry/utils/queryString'; import {MutableSearch} from 'sentry/utils/tokenizeSearch'; -import normalizeUrl from 'sentry/utils/url/normalizeUrl'; import useLocationQuery from 'sentry/utils/url/useLocationQuery'; import {useLocation} from 'sentry/utils/useLocation'; import {useNavigate} from 'sentry/utils/useNavigate'; @@ -27,7 +22,6 @@ import {TransactionDurationChart} from 'sentry/views/insights/cache/components/c import {SpanSamplesTable} from 'sentry/views/insights/cache/components/tables/spanSamplesTable'; import {Referrer} from 'sentry/views/insights/cache/referrers'; import {BASE_FILTERS} from 'sentry/views/insights/cache/settings'; -import DetailPanel from 'sentry/views/insights/common/components/detailPanel'; import {MetricReadout} from 'sentry/views/insights/common/components/metricReadout'; import * as ModuleLayout from 'sentry/views/insights/common/components/moduleLayout'; import {ReadoutRibbon} from 'sentry/views/insights/common/components/ribbon'; @@ -45,7 +39,6 @@ import { getThroughputTitle, } from 'sentry/views/insights/common/views/spans/types'; import {useDebouncedState} from 'sentry/views/insights/http/utils/useDebouncedState'; -import {useDomainViewFilters} from 'sentry/views/insights/pages/useFilters'; import { MetricsFields, type MetricsQueryFilters, @@ -57,7 +50,9 @@ import { SpanMetricsField, type SpanMetricsQueryFilters, } from 'sentry/views/insights/types'; -import {getTransactionSummaryBaseUrl} from 'sentry/views/performance/transactionSummary/utils'; + +import {SampleDrawerBody} from '../../common/components/sampleDrawerBody'; +import {SampleDrawerHeaderTransaction} from '../../common/components/sampleDrawerHeaderTransaction'; // This is similar to http sample table, its difficult to use the generic span samples sidebar as we require a bunch of custom things. export function CacheSamplePanel() { @@ -65,7 +60,6 @@ export function CacheSamplePanel() { const location = useLocation(); const organization = useOrganization(); const {selection} = usePageFilters(); - const {view} = useDomainViewFilters(); const query = useLocationQuery({ fields: { @@ -239,26 +233,6 @@ export function CacheSamplePanel() { }); }; - const handleClose = () => { - navigate({ - pathname: location.pathname, - query: { - ...location.query, - transaction: undefined, - transactionMethod: undefined, - }, - }); - }; - - const handleOpen = useCallback(() => { - if (query.transaction) { - trackAnalytics('performance_views.sample_spans.opened', { - organization, - source: ModuleName.CACHE, - }); - } - }, [organization, query.transaction]); - const handleRefetch = () => { refetchCacheHits(); refetchCacheMisses(); @@ -266,36 +240,17 @@ export function CacheSamplePanel() { return ( - + + {project && ( + + )} + + + - - - {project && ( - - )} - - <Link - to={normalizeUrl( - `${getTransactionSummaryBaseUrl(organization.slug, view)}?${qs.stringify( - { - project: query.project, - transaction: query.transaction, - } - )}` - )} - > - {query.transaction} - </Link> - - - - - + ); } @@ -463,26 +418,3 @@ const CACHE_STATUS_OPTIONS = [ label: t('Miss'), }, ]; - -const SpanSummaryProjectAvatar = styled(ProjectAvatar)` - padding-right: ${space(1)}; -`; - -// TODO - copy of static/app/views/starfish/views/spanSummaryPage/sampleList/index.tsx -const HeaderContainer = styled('div')` - display: grid; - grid-template-rows: auto auto auto; - align-items: center; - - @media (min-width: ${p => p.theme.breakpoints.small}) { - grid-template-rows: auto; - grid-template-columns: auto 1fr; - } -`; - -const Title = styled('h4')` - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - margin: 0; -`; diff --git a/static/app/views/insights/cache/views/cacheLandingPage.tsx b/static/app/views/insights/cache/views/cacheLandingPage.tsx index f3194f6fb587e2..fdd7f61aee1602 100644 --- a/static/app/views/insights/cache/views/cacheLandingPage.tsx +++ b/static/app/views/insights/cache/views/cacheLandingPage.tsx @@ -14,6 +14,7 @@ import { } from 'sentry/utils/performance/contexts/pageAlert'; import {decodeScalar, decodeSorts} from 'sentry/utils/queryString'; import {MutableSearch} from 'sentry/utils/tokenizeSearch'; +import useLocationQuery from 'sentry/utils/url/useLocationQuery'; import {useLocation} from 'sentry/utils/useLocation'; import {CacheHitMissChart} from 'sentry/views/insights/cache/components/charts/hitMissChart'; import {ThroughputChart} from 'sentry/views/insights/cache/components/charts/throughputChart'; @@ -46,6 +47,8 @@ import {DataTitles} from 'sentry/views/insights/common/views/spans/types'; import {BackendHeader} from 'sentry/views/insights/pages/backend/backendPageHeader'; import {ModuleName, SpanFunction, SpanMetricsField} from 'sentry/views/insights/types'; +import {useSamplesDrawer} from '../../common/utils/useSamplesDrawer'; + const {CACHE_MISS_RATE} = SpanFunction; const {CACHE_ITEM_SIZE} = SpanMetricsField; @@ -71,6 +74,23 @@ export function CacheLandingPage() { const sort = decodeSorts(sortField).filter(isAValidSort).at(0) ?? DEFAULT_SORT; const cursor = decodeScalar(location.query?.[QueryParameterNames.TRANSACTIONS_CURSOR]); + const query = useLocationQuery({ + fields: { + transaction: decodeScalar, + }, + }); + + const {openSamplesDrawer} = useSamplesDrawer({ + Component: CacheSamplePanel, + moduleName: ModuleName.CACHE, + }); + + useEffect(() => { + if (query.transaction) { + openSamplesDrawer(); + } + }); + const { isPending: isCacheMissRateLoading, data: cacheMissRateData, @@ -233,7 +253,6 @@ export function CacheLandingPage() { - ); } From 0798e8c91fd7ff78b9a46fb93a52dd3825f23a29 Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Fri, 20 Dec 2024 18:36:03 -0500 Subject: [PATCH 07/37] Use new Drawer in Queues --- .../components/messageSpanSamplesPanel.tsx | 107 +++--------------- .../queues/views/destinationSummaryPage.tsx | 16 ++- 2 files changed, 29 insertions(+), 94 deletions(-) diff --git a/static/app/views/insights/queues/components/messageSpanSamplesPanel.tsx b/static/app/views/insights/queues/components/messageSpanSamplesPanel.tsx index 9fcd6566105986..38080a3fd51c07 100644 --- a/static/app/views/insights/queues/components/messageSpanSamplesPanel.tsx +++ b/static/app/views/insights/queues/components/messageSpanSamplesPanel.tsx @@ -1,11 +1,8 @@ -import {useCallback} from 'react'; import styled from '@emotion/styled'; -import * as qs from 'query-string'; -import ProjectAvatar from 'sentry/components/avatar/projectAvatar'; import {Button} from 'sentry/components/button'; import {CompactSelect, type SelectOption} from 'sentry/components/compactSelect'; -import Link from 'sentry/components/links/link'; +import {DrawerHeader} from 'sentry/components/globalDrawer/components'; import {SpanSearchQueryBuilder} from 'sentry/components/performance/spanSearchQueryBuilder'; import {t} from 'sentry/locale'; import {space} from 'sentry/styles/space'; @@ -21,7 +18,6 @@ import useOrganization from 'sentry/utils/useOrganization'; import usePageFilters from 'sentry/utils/usePageFilters'; import useProjects from 'sentry/utils/useProjects'; import {computeAxisMax} from 'sentry/views/insights/common/components/chart'; -import DetailPanel from 'sentry/views/insights/common/components/detailPanel'; import {MetricReadout} from 'sentry/views/insights/common/components/metricReadout'; import * as ModuleLayout from 'sentry/views/insights/common/components/moduleLayout'; import {ReadoutRibbon} from 'sentry/views/insights/common/components/ribbon'; @@ -31,7 +27,6 @@ import {useSampleScatterPlotSeries} from 'sentry/views/insights/common/views/spa import {DurationChartWithSamples} from 'sentry/views/insights/http/components/charts/durationChartWithSamples'; import {useSpanSamples} from 'sentry/views/insights/http/queries/useSpanSamples'; import {useDebouncedState} from 'sentry/views/insights/http/utils/useDebouncedState'; -import {useDomainViewFilters} from 'sentry/views/insights/pages/useFilters'; import {MessageSpanSamplesTable} from 'sentry/views/insights/queues/components/tables/messageSpanSamplesTable'; import {useQueuesMetricsQuery} from 'sentry/views/insights/queues/queries/useQueuesMetricsQuery'; import {Referrer} from 'sentry/views/insights/queues/referrers'; @@ -49,8 +44,9 @@ import { SpanIndexedField, type SpanMetricsResponse, } from 'sentry/views/insights/types'; -import {getTransactionSummaryBaseUrl} from 'sentry/views/performance/transactionSummary/utils'; -import {Subtitle} from 'sentry/views/profiling/landing/styles'; + +import {SampleDrawerBody} from '../../common/components/sampleDrawerBody'; +import {SampleDrawerHeaderTransaction} from '../../common/components/sampleDrawerHeaderTransaction'; export function MessageSpanSamplesPanel() { const navigate = useNavigate(); @@ -72,7 +68,6 @@ export function MessageSpanSamplesPanel() { const project = projects.find(p => query.project === p.id); const organization = useOrganization(); - const {view} = useDomainViewFilters(); const [highlightedSpanId, setHighlightedSpanId] = useDebouncedState( undefined, @@ -228,65 +223,19 @@ export function MessageSpanSamplesPanel() { }); }; - const handleClose = () => { - navigate({ - pathname: location.pathname, - query: { - ...location.query, - transaction: undefined, - transactionMethod: undefined, - }, - }); - }; - - const handleOpen = useCallback(() => { - if (query.transaction) { - trackAnalytics('performance_views.sample_spans.opened', { - organization, - source: ModuleName.QUEUE, - }); - } - }, [organization, query.transaction]); - return ( - + + {project && ( + + )} + + + - - - {project ? ( - - ) : ( -
- )} - - - {messageActorType === MessageActorType.PRODUCER - ? t('Producer') - : t('Consumer')} - - - <Link - to={`${getTransactionSummaryBaseUrl(organization.slug, view)}?${qs.stringify( - { - project: query.project, - transaction: query.transaction, - } - )}`} - > - {query.transaction} - </Link> - - - - - {messageActorType === MessageActorType.PRODUCER ? ( @@ -400,7 +349,7 @@ export function MessageSpanSamplesPanel() { - + ); } @@ -497,32 +446,6 @@ const RETRY_COUNT_SELECT_OPTIONS = [ }), ]; -const SpanSummaryProjectAvatar = styled(ProjectAvatar)` - padding-right: ${space(1)}; -`; - -const HeaderContainer = styled('div')` - display: grid; - grid-template-rows: auto auto auto; - - @media (min-width: ${p => p.theme.breakpoints.small}) { - grid-template-rows: auto; - grid-template-columns: auto 1fr; - } -`; - -const TitleContainer = styled('div')` - width: 100%; - overflow: hidden; -`; - -const Title = styled('h4')` - overflow: inherit; - text-overflow: ellipsis; - white-space: nowrap; - margin: 0; -`; - const MetricsRibbonContainer = styled('div')` display: flex; flex-wrap: wrap; diff --git a/static/app/views/insights/queues/views/destinationSummaryPage.tsx b/static/app/views/insights/queues/views/destinationSummaryPage.tsx index 549fe1c419d7e4..2645cb130487c3 100644 --- a/static/app/views/insights/queues/views/destinationSummaryPage.tsx +++ b/static/app/views/insights/queues/views/destinationSummaryPage.tsx @@ -1,4 +1,4 @@ -import {Fragment} from 'react'; +import {Fragment, useEffect} from 'react'; import styled from '@emotion/styled'; import * as Layout from 'sentry/components/layouts/thirds'; @@ -28,6 +28,8 @@ import {DESTINATION_TITLE} from 'sentry/views/insights/queues/settings'; import {ModuleName} from 'sentry/views/insights/types'; import Onboarding from 'sentry/views/performance/onboarding'; +import {useSamplesDrawer} from '../../common/utils/useSamplesDrawer'; + function DestinationSummaryPage() { const organization = useOrganization(); const onboardingProject = useOnboardingProject(); @@ -41,6 +43,17 @@ function DestinationSummaryPage() { }); const errorRate = 1 - (data[0]?.['trace_status_rate(ok)'] ?? 0); + const {openSamplesDrawer} = useSamplesDrawer({ + Component: MessageSpanSamplesPanel, + moduleName: ModuleName.QUEUE, + }); + + useEffect(() => { + if (query.transaction) { + openSamplesDrawer(); + } + }); + return ( - ); } From eb92e0d8f082e13f5d7ede7e6d9b3c7fbdc3a03c Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Fri, 20 Dec 2024 18:43:56 -0500 Subject: [PATCH 08/37] Pass through a React node instead --- static/app/views/insights/cache/views/cacheLandingPage.tsx | 2 +- static/app/views/insights/common/utils/useSamplesDrawer.tsx | 4 ++-- .../app/views/insights/http/views/httpDomainSummaryPage.tsx | 2 +- .../views/insights/queues/views/destinationSummaryPage.tsx | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/static/app/views/insights/cache/views/cacheLandingPage.tsx b/static/app/views/insights/cache/views/cacheLandingPage.tsx index fdd7f61aee1602..4e2079a611901e 100644 --- a/static/app/views/insights/cache/views/cacheLandingPage.tsx +++ b/static/app/views/insights/cache/views/cacheLandingPage.tsx @@ -81,7 +81,7 @@ export function CacheLandingPage() { }); const {openSamplesDrawer} = useSamplesDrawer({ - Component: CacheSamplePanel, + Component: , moduleName: ModuleName.CACHE, }); diff --git a/static/app/views/insights/common/utils/useSamplesDrawer.tsx b/static/app/views/insights/common/utils/useSamplesDrawer.tsx index 381ab1c839d1e5..aa44c69912a3ac 100644 --- a/static/app/views/insights/common/utils/useSamplesDrawer.tsx +++ b/static/app/views/insights/common/utils/useSamplesDrawer.tsx @@ -10,7 +10,7 @@ import useOrganization from 'sentry/utils/useOrganization'; import type {ModuleName} from '../../types'; interface UseSamplesDrawerProps { - Component: React.FunctionComponent; + Component: React.ReactNode; moduleName: ModuleName; } @@ -36,7 +36,7 @@ export function useSamplesDrawer({Component, moduleName}: UseSamplesDrawerProps) source: moduleName, }); - openDrawer(() => , { + openDrawer(() => Component, { ariaLabel: t('Samples'), onClose, transitionProps: {stiffness: 1000}, diff --git a/static/app/views/insights/http/views/httpDomainSummaryPage.tsx b/static/app/views/insights/http/views/httpDomainSummaryPage.tsx index 00f42087a0bbcb..147957045d8f31 100644 --- a/static/app/views/insights/http/views/httpDomainSummaryPage.tsx +++ b/static/app/views/insights/http/views/httpDomainSummaryPage.tsx @@ -89,7 +89,7 @@ export function HTTPDomainSummaryPage() { }); const {openSamplesDrawer} = useSamplesDrawer({ - Component: HTTPSamplesPanel, + Component: , moduleName: ModuleName.HTTP, }); diff --git a/static/app/views/insights/queues/views/destinationSummaryPage.tsx b/static/app/views/insights/queues/views/destinationSummaryPage.tsx index 2645cb130487c3..47d606966f6a6a 100644 --- a/static/app/views/insights/queues/views/destinationSummaryPage.tsx +++ b/static/app/views/insights/queues/views/destinationSummaryPage.tsx @@ -44,7 +44,7 @@ function DestinationSummaryPage() { const errorRate = 1 - (data[0]?.['trace_status_rate(ok)'] ?? 0); const {openSamplesDrawer} = useSamplesDrawer({ - Component: MessageSpanSamplesPanel, + Component: , moduleName: ModuleName.QUEUE, }); From 4e474addae6ed91742bad70824db2e791baaabb6 Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Fri, 20 Dec 2024 18:44:09 -0500 Subject: [PATCH 09/37] Omit query when closing the drawer --- static/app/views/insights/common/utils/useSamplesDrawer.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/static/app/views/insights/common/utils/useSamplesDrawer.tsx b/static/app/views/insights/common/utils/useSamplesDrawer.tsx index aa44c69912a3ac..ddc0820e3fa058 100644 --- a/static/app/views/insights/common/utils/useSamplesDrawer.tsx +++ b/static/app/views/insights/common/utils/useSamplesDrawer.tsx @@ -26,6 +26,7 @@ export function useSamplesDrawer({Component, moduleName}: UseSamplesDrawerProps) ...location.query, transaction: undefined, transactionMethod: undefined, + query: undefined, }, }); }, [navigate, location.query]); From f3b970f66c8bfb9df380dfaf51ccab4621519254 Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Fri, 20 Dec 2024 18:50:32 -0500 Subject: [PATCH 10/37] Use new Drawer in Queries and Resources --- .../resources/views/resourceSummaryPage.tsx | 35 ++++-- .../spanSummaryPage/sampleList/index.tsx | 107 +++--------------- .../views/databaseSpanSummaryPage.tsx | 31 +++-- 3 files changed, 61 insertions(+), 112 deletions(-) diff --git a/static/app/views/insights/browser/resources/views/resourceSummaryPage.tsx b/static/app/views/insights/browser/resources/views/resourceSummaryPage.tsx index a82dc06d91efcc..2971e62beaa5ac 100644 --- a/static/app/views/insights/browser/resources/views/resourceSummaryPage.tsx +++ b/static/app/views/insights/browser/resources/views/resourceSummaryPage.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, {useEffect} from 'react'; import * as Layout from 'sentry/components/layouts/thirds'; import {t, tct} from 'sentry/locale'; @@ -23,6 +23,7 @@ import {ModuleBodyUpsellHook} from 'sentry/views/insights/common/components/modu import {ToolRibbon} from 'sentry/views/insights/common/components/ribbon'; import {useSpanMetrics} from 'sentry/views/insights/common/queries/useDiscover'; import {useModuleURL} from 'sentry/views/insights/common/utils/useModuleURL'; +import {useSamplesDrawer} from 'sentry/views/insights/common/utils/useSamplesDrawer'; import SubregionSelector from 'sentry/views/insights/common/views/spans/selectors/subregionSelector'; import {SampleList} from 'sentry/views/insights/common/views/spanSummaryPage/sampleList'; import {FrontendHeader} from 'sentry/views/insights/pages/frontend/frontendPageHeader'; @@ -47,6 +48,27 @@ function ResourceSummary() { const { query: {transaction}, } = useLocation(); + + const {openSamplesDrawer} = useSamplesDrawer({ + Component: ( + + ), + moduleName: ModuleName.RESOURCE, + }); + + useEffect(() => { + if (transaction) { + openSamplesDrawer(); + } + }); + const {data, isPending} = useSpanMetrics( { search: MutableSearch.fromQueryObject({ @@ -139,17 +161,6 @@ function ResourceSummary() { - - - - diff --git a/static/app/views/insights/common/views/spanSummaryPage/sampleList/index.tsx b/static/app/views/insights/common/views/spanSummaryPage/sampleList/index.tsx index 2254984b270aae..be6703cfafbc5b 100644 --- a/static/app/views/insights/common/views/spanSummaryPage/sampleList/index.tsx +++ b/static/app/views/insights/common/views/spanSummaryPage/sampleList/index.tsx @@ -1,28 +1,22 @@ import {useCallback, useMemo, useState} from 'react'; import styled from '@emotion/styled'; import debounce from 'lodash/debounce'; -import omit from 'lodash/omit'; -import * as qs from 'query-string'; -import ProjectAvatar from 'sentry/components/avatar/projectAvatar'; +import {DrawerHeader} from 'sentry/components/globalDrawer/components'; import {COL_WIDTH_UNDEFINED} from 'sentry/components/gridEditable'; -import Link from 'sentry/components/links/link'; import {SpanSearchQueryBuilder} from 'sentry/components/performance/spanSearchQueryBuilder'; import {t} from 'sentry/locale'; import {space} from 'sentry/styles/space'; -import {trackAnalytics} from 'sentry/utils/analytics'; import {generateLinkToEventInTraceView} from 'sentry/utils/discover/urls'; import {PageAlert, PageAlertProvider} from 'sentry/utils/performance/contexts/pageAlert'; import {decodeScalar} from 'sentry/utils/queryString'; import {MutableSearch} from 'sentry/utils/tokenizeSearch'; -import normalizeUrl from 'sentry/utils/url/normalizeUrl'; import {useLocation} from 'sentry/utils/useLocation'; import useOrganization from 'sentry/utils/useOrganization'; import usePageFilters from 'sentry/utils/usePageFilters'; import useProjects from 'sentry/utils/useProjects'; import useRouter from 'sentry/utils/useRouter'; import {DATA_TYPE} from 'sentry/views/insights/browser/resources/settings'; -import DetailPanel from 'sentry/views/insights/common/components/detailPanel'; import {DEFAULT_COLUMN_ORDER} from 'sentry/views/insights/common/components/samplesTable/spanSamplesTable'; import DurationChart from 'sentry/views/insights/common/views/spanSummaryPage/sampleList/durationChart'; import SampleInfo from 'sentry/views/insights/common/views/spanSummaryPage/sampleList/sampleInfo'; @@ -36,13 +30,15 @@ import { } from 'sentry/views/insights/types'; import {getTransactionSummaryBaseUrl} from 'sentry/views/performance/transactionSummary/utils'; +import {SampleDrawerBody} from '../../../components/sampleDrawerBody'; +import {SampleDrawerHeaderTransaction} from '../../../components/sampleDrawerHeaderTransaction'; + const {HTTP_RESPONSE_CONTENT_LENGTH, SPAN_DESCRIPTION} = SpanMetricsField; type Props = { groupId: string; moduleName: ModuleName; transactionName: string; - onClose?: () => void; referrer?: string; subregions?: SubregionCode[]; transactionMethod?: string; @@ -55,7 +51,6 @@ export function SampleList({ transactionName, transactionMethod, subregions, - onClose, transactionRoute, referrer, }: Props) { @@ -68,12 +63,6 @@ export function SampleList({ transactionRoute ??= `/${getTransactionSummaryBaseUrl(organization.slug, view, true)}`; - // A a transaction name is required to show the panel, but a transaction - // method is not - const detailKey = transactionName - ? [groupId, transactionName, transactionMethod].filter(Boolean).join(':') - : undefined; - // eslint-disable-next-line react-hooks/exhaustive-deps const debounceSetHighlightedSpanId = useCallback( debounce(id => { @@ -103,27 +92,6 @@ export function SampleList({ }); }; - const onOpenDetailPanel = useCallback(() => { - if (location.query.transaction) { - trackAnalytics('performance_views.sample_spans.opened', { - organization, - source: moduleName, - }); - } - }, [organization, location.query.transaction, moduleName]); - - const label = - transactionMethod && !transactionName.startsWith(transactionMethod) - ? `${transactionMethod} ${transactionName}` - : transactionName; - - const link = normalizeUrl( - `/organizations/${organization.slug}${transactionRoute}?${qs.stringify({ - project: location.query.project, - transaction: transactionName, - })}` - ); - // set additional query filters from the span search bar and the `query` param const spanSearch = new MutableSearch(spanSearchQuery ?? ''); if (location.query.query) { @@ -135,13 +103,6 @@ export function SampleList({ }); } - function defaultOnClose() { - router.replace({ - pathname: router.location.pathname, - query: omit(router.location.query, 'transaction', 'transactionMethod', 'query'), - }); - } - let columnOrder = DEFAULT_COLUMN_ORDER; const additionalFields: SpanIndexedField[] = [ @@ -170,27 +131,17 @@ export function SampleList({ return ( - { - onClose ? onClose() : defaultOnClose(); - }} - onOpen={onOpenDetailPanel} - > - - {project && ( - - )} - - <Link to={link}>{label}</Link> - - + + {project && ( + + )} + + + - + ); } -const SpanSummaryProjectAvatar = styled(ProjectAvatar)` - padding-right: ${space(1)}; -`; - -const HeaderContainer = styled('div')` - width: 100%; - padding-bottom: ${space(2)}; - padding-top: ${space(1)}; - - display: grid; - grid-template-rows: auto auto auto; - align-items: center; - - @media (min-width: ${p => p.theme.breakpoints.small}) { - grid-template-rows: auto; - grid-template-columns: auto 1fr; - } -`; - -const Title = styled('h4')` - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - margin: 0; -`; - const StyledSearchBar = styled('div')` margin: ${space(2)} 0; `; diff --git a/static/app/views/insights/database/views/databaseSpanSummaryPage.tsx b/static/app/views/insights/database/views/databaseSpanSummaryPage.tsx index a9d811259a7261..bbbbd7dff1fe03 100644 --- a/static/app/views/insights/database/views/databaseSpanSummaryPage.tsx +++ b/static/app/views/insights/database/views/databaseSpanSummaryPage.tsx @@ -1,4 +1,4 @@ -import {Fragment} from 'react'; +import {Fragment, useEffect} from 'react'; import styled from '@emotion/styled'; import Feature from 'sentry/components/acl/feature'; @@ -47,6 +47,8 @@ import { } from 'sentry/views/insights/types'; import {TraceViewSources} from 'sentry/views/performance/newTraceDetails/traceHeader/breadcrumbs'; +import {useSamplesDrawer} from '../../common/utils/useSamplesDrawer'; + type Query = { transaction: string; transactionMethod: string; @@ -147,6 +149,25 @@ export function DatabaseSpanSummaryPage({params}: Props) { [SpanMetricsField.SPAN_GROUP]: string; }; + const {openSamplesDrawer} = useSamplesDrawer({ + Component: ( + + ), + moduleName: ModuleName.DB, + }); + + useEffect(() => { + if (transaction) { + openSamplesDrawer(); + } + }); + const { isPending: isThroughputDataLoading, data: throughputData, @@ -286,14 +307,6 @@ export function DatabaseSpanSummaryPage({params}: Props) { )} - - From 0c48ed6d84de5798763bd88a22590080cfbe461a Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 09:29:08 -0500 Subject: [PATCH 11/37] Custon `onClose` Unfortunately the re-use is not as consistent as I hoped. --- .../resources/views/resourceSummaryPage.tsx | 17 +++++++++++--- .../insights/cache/views/cacheLandingPage.tsx | 12 ++++++++++ .../common/utils/useSamplesDrawer.tsx | 22 +++++-------------- .../views/databaseSpanSummaryPage.tsx | 12 ++++++++++ .../http/views/httpDomainSummaryPage.tsx | 12 ++++++++++ .../queues/views/destinationSummaryPage.tsx | 12 ++++++++++ 6 files changed, 68 insertions(+), 19 deletions(-) diff --git a/static/app/views/insights/browser/resources/views/resourceSummaryPage.tsx b/static/app/views/insights/browser/resources/views/resourceSummaryPage.tsx index 2971e62beaa5ac..089c04dbdfebc4 100644 --- a/static/app/views/insights/browser/resources/views/resourceSummaryPage.tsx +++ b/static/app/views/insights/browser/resources/views/resourceSummaryPage.tsx @@ -4,6 +4,7 @@ import * as Layout from 'sentry/components/layouts/thirds'; import {t, tct} from 'sentry/locale'; import {MutableSearch} from 'sentry/utils/tokenizeSearch'; import {useLocation} from 'sentry/utils/useLocation'; +import {useNavigate} from 'sentry/utils/useNavigate'; import {useParams} from 'sentry/utils/useParams'; import ResourceSummaryCharts from 'sentry/views/insights/browser/resources/components/charts/resourceSummaryCharts'; import RenderBlockingSelector from 'sentry/views/insights/browser/resources/components/renderBlockingSelector'; @@ -45,9 +46,10 @@ function ResourceSummary() { const {groupId} = useParams(); const filters = useResourceModuleFilters(); const selectedSpanOp = filters[SPAN_OP]; - const { - query: {transaction}, - } = useLocation(); + const location = useLocation(); + const {transaction} = location.query; + + const navigate = useNavigate(); const {openSamplesDrawer} = useSamplesDrawer({ Component: ( @@ -61,6 +63,15 @@ function ResourceSummary() { /> ), moduleName: ModuleName.RESOURCE, + onClose: () => { + navigate({ + query: { + ...location.query, + transaction: undefined, + transactionMethod: undefined, + }, + }); + }, }); useEffect(() => { diff --git a/static/app/views/insights/cache/views/cacheLandingPage.tsx b/static/app/views/insights/cache/views/cacheLandingPage.tsx index 4e2079a611901e..7ab3f06e4b957e 100644 --- a/static/app/views/insights/cache/views/cacheLandingPage.tsx +++ b/static/app/views/insights/cache/views/cacheLandingPage.tsx @@ -16,6 +16,7 @@ import {decodeScalar, decodeSorts} from 'sentry/utils/queryString'; import {MutableSearch} from 'sentry/utils/tokenizeSearch'; import useLocationQuery from 'sentry/utils/url/useLocationQuery'; import {useLocation} from 'sentry/utils/useLocation'; +import {useNavigate} from 'sentry/utils/useNavigate'; import {CacheHitMissChart} from 'sentry/views/insights/cache/components/charts/hitMissChart'; import {ThroughputChart} from 'sentry/views/insights/cache/components/charts/throughputChart'; import {CacheSamplePanel} from 'sentry/views/insights/cache/components/samplePanel'; @@ -80,9 +81,20 @@ export function CacheLandingPage() { }, }); + const navigate = useNavigate(); + const {openSamplesDrawer} = useSamplesDrawer({ Component: , moduleName: ModuleName.CACHE, + onClose: () => { + navigate({ + query: { + ...location.query, + transaction: undefined, + transactionMethod: undefined, + }, + }); + }, }); useEffect(() => { diff --git a/static/app/views/insights/common/utils/useSamplesDrawer.tsx b/static/app/views/insights/common/utils/useSamplesDrawer.tsx index ddc0820e3fa058..37e77d749ea24b 100644 --- a/static/app/views/insights/common/utils/useSamplesDrawer.tsx +++ b/static/app/views/insights/common/utils/useSamplesDrawer.tsx @@ -3,8 +3,6 @@ import {useCallback} from 'react'; import useDrawer from 'sentry/components/globalDrawer'; import {t} from 'sentry/locale'; import {trackAnalytics} from 'sentry/utils/analytics'; -import {useLocation} from 'sentry/utils/useLocation'; -import {useNavigate} from 'sentry/utils/useNavigate'; import useOrganization from 'sentry/utils/useOrganization'; import type {ModuleName} from '../../types'; @@ -12,24 +10,16 @@ import type {ModuleName} from '../../types'; interface UseSamplesDrawerProps { Component: React.ReactNode; moduleName: ModuleName; + onClose: () => void; } -export function useSamplesDrawer({Component, moduleName}: UseSamplesDrawerProps) { +export function useSamplesDrawer({ + Component, + moduleName, + onClose, +}: UseSamplesDrawerProps) { const organization = useOrganization(); const {openDrawer} = useDrawer(); - const navigate = useNavigate(); - const location = useLocation(); - - const onClose = useCallback(() => { - navigate({ - query: { - ...location.query, - transaction: undefined, - transactionMethod: undefined, - query: undefined, - }, - }); - }, [navigate, location.query]); const openSamplesDrawer = useCallback(() => { trackAnalytics('performance_views.sample_spans.opened', { diff --git a/static/app/views/insights/database/views/databaseSpanSummaryPage.tsx b/static/app/views/insights/database/views/databaseSpanSummaryPage.tsx index bbbbd7dff1fe03..43065066149252 100644 --- a/static/app/views/insights/database/views/databaseSpanSummaryPage.tsx +++ b/static/app/views/insights/database/views/databaseSpanSummaryPage.tsx @@ -10,6 +10,7 @@ import {DurationUnit, RateUnit} from 'sentry/utils/discover/fields'; import {decodeScalar, decodeSorts} from 'sentry/utils/queryString'; import {MutableSearch} from 'sentry/utils/tokenizeSearch'; import {useLocation} from 'sentry/utils/useLocation'; +import {useNavigate} from 'sentry/utils/useNavigate'; import {useSynchronizeCharts} from 'sentry/views/insights/common/components/chart'; import {HeaderContainer} from 'sentry/views/insights/common/components/headerContainer'; import InsightIssuesList from 'sentry/views/insights/common/components/issues'; @@ -149,6 +150,8 @@ export function DatabaseSpanSummaryPage({params}: Props) { [SpanMetricsField.SPAN_GROUP]: string; }; + const navigate = useNavigate(); + const {openSamplesDrawer} = useSamplesDrawer({ Component: ( ), moduleName: ModuleName.DB, + onClose: () => { + navigate({ + query: { + ...location.query, + transaction: undefined, + transactionMethod: undefined, + }, + }); + }, }); useEffect(() => { diff --git a/static/app/views/insights/http/views/httpDomainSummaryPage.tsx b/static/app/views/insights/http/views/httpDomainSummaryPage.tsx index 147957045d8f31..fc94666062a24c 100644 --- a/static/app/views/insights/http/views/httpDomainSummaryPage.tsx +++ b/static/app/views/insights/http/views/httpDomainSummaryPage.tsx @@ -14,6 +14,7 @@ import { } from 'sentry/utils/tokenizeSearch'; import useLocationQuery from 'sentry/utils/url/useLocationQuery'; import {useLocation} from 'sentry/utils/useLocation'; +import {useNavigate} from 'sentry/utils/useNavigate'; import useProjects from 'sentry/utils/useProjects'; import {useSynchronizeCharts} from 'sentry/views/insights/common/components/chart'; import {HeaderContainer} from 'sentry/views/insights/common/components/headerContainer'; @@ -88,9 +89,20 @@ export function HTTPDomainSummaryPage() { }, }); + const navigate = useNavigate(); + const {openSamplesDrawer} = useSamplesDrawer({ Component: , moduleName: ModuleName.HTTP, + onClose: () => { + navigate({ + query: { + ...location.query, + transaction: undefined, + transactionMethod: undefined, + }, + }); + }, }); useEffect(() => { diff --git a/static/app/views/insights/queues/views/destinationSummaryPage.tsx b/static/app/views/insights/queues/views/destinationSummaryPage.tsx index 47d606966f6a6a..06a16e1557b490 100644 --- a/static/app/views/insights/queues/views/destinationSummaryPage.tsx +++ b/static/app/views/insights/queues/views/destinationSummaryPage.tsx @@ -7,6 +7,7 @@ import {space} from 'sentry/styles/space'; import {DurationUnit} from 'sentry/utils/discover/fields'; import {decodeScalar} from 'sentry/utils/queryString'; import {useLocation} from 'sentry/utils/useLocation'; +import {useNavigate} from 'sentry/utils/useNavigate'; import useOrganization from 'sentry/utils/useOrganization'; import {HeaderContainer} from 'sentry/views/insights/common/components/headerContainer'; import {MetricReadout} from 'sentry/views/insights/common/components/metricReadout'; @@ -43,9 +44,20 @@ function DestinationSummaryPage() { }); const errorRate = 1 - (data[0]?.['trace_status_rate(ok)'] ?? 0); + const navigate = useNavigate(); + const {openSamplesDrawer} = useSamplesDrawer({ Component: , moduleName: ModuleName.QUEUE, + onClose: () => { + navigate({ + query: { + ...query, + transaction: undefined, + transactionMethod: undefined, + }, + }); + }, }); useEffect(() => { From 232eea86b2e8b33b459aa362784aeb7e3f4d745f Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 09:37:35 -0500 Subject: [PATCH 12/37] Revert "Custon `onClose`" This reverts commit 3e54ef6c8207ae5533f77093d664e59bad12b303. --- .../resources/views/resourceSummaryPage.tsx | 17 +++----------- .../insights/cache/views/cacheLandingPage.tsx | 12 ---------- .../common/utils/useSamplesDrawer.tsx | 22 ++++++++++++++----- .../views/databaseSpanSummaryPage.tsx | 12 ---------- .../http/views/httpDomainSummaryPage.tsx | 12 ---------- .../queues/views/destinationSummaryPage.tsx | 12 ---------- 6 files changed, 19 insertions(+), 68 deletions(-) diff --git a/static/app/views/insights/browser/resources/views/resourceSummaryPage.tsx b/static/app/views/insights/browser/resources/views/resourceSummaryPage.tsx index 089c04dbdfebc4..2971e62beaa5ac 100644 --- a/static/app/views/insights/browser/resources/views/resourceSummaryPage.tsx +++ b/static/app/views/insights/browser/resources/views/resourceSummaryPage.tsx @@ -4,7 +4,6 @@ import * as Layout from 'sentry/components/layouts/thirds'; import {t, tct} from 'sentry/locale'; import {MutableSearch} from 'sentry/utils/tokenizeSearch'; import {useLocation} from 'sentry/utils/useLocation'; -import {useNavigate} from 'sentry/utils/useNavigate'; import {useParams} from 'sentry/utils/useParams'; import ResourceSummaryCharts from 'sentry/views/insights/browser/resources/components/charts/resourceSummaryCharts'; import RenderBlockingSelector from 'sentry/views/insights/browser/resources/components/renderBlockingSelector'; @@ -46,10 +45,9 @@ function ResourceSummary() { const {groupId} = useParams(); const filters = useResourceModuleFilters(); const selectedSpanOp = filters[SPAN_OP]; - const location = useLocation(); - const {transaction} = location.query; - - const navigate = useNavigate(); + const { + query: {transaction}, + } = useLocation(); const {openSamplesDrawer} = useSamplesDrawer({ Component: ( @@ -63,15 +61,6 @@ function ResourceSummary() { /> ), moduleName: ModuleName.RESOURCE, - onClose: () => { - navigate({ - query: { - ...location.query, - transaction: undefined, - transactionMethod: undefined, - }, - }); - }, }); useEffect(() => { diff --git a/static/app/views/insights/cache/views/cacheLandingPage.tsx b/static/app/views/insights/cache/views/cacheLandingPage.tsx index 7ab3f06e4b957e..4e2079a611901e 100644 --- a/static/app/views/insights/cache/views/cacheLandingPage.tsx +++ b/static/app/views/insights/cache/views/cacheLandingPage.tsx @@ -16,7 +16,6 @@ import {decodeScalar, decodeSorts} from 'sentry/utils/queryString'; import {MutableSearch} from 'sentry/utils/tokenizeSearch'; import useLocationQuery from 'sentry/utils/url/useLocationQuery'; import {useLocation} from 'sentry/utils/useLocation'; -import {useNavigate} from 'sentry/utils/useNavigate'; import {CacheHitMissChart} from 'sentry/views/insights/cache/components/charts/hitMissChart'; import {ThroughputChart} from 'sentry/views/insights/cache/components/charts/throughputChart'; import {CacheSamplePanel} from 'sentry/views/insights/cache/components/samplePanel'; @@ -81,20 +80,9 @@ export function CacheLandingPage() { }, }); - const navigate = useNavigate(); - const {openSamplesDrawer} = useSamplesDrawer({ Component: , moduleName: ModuleName.CACHE, - onClose: () => { - navigate({ - query: { - ...location.query, - transaction: undefined, - transactionMethod: undefined, - }, - }); - }, }); useEffect(() => { diff --git a/static/app/views/insights/common/utils/useSamplesDrawer.tsx b/static/app/views/insights/common/utils/useSamplesDrawer.tsx index 37e77d749ea24b..ddc0820e3fa058 100644 --- a/static/app/views/insights/common/utils/useSamplesDrawer.tsx +++ b/static/app/views/insights/common/utils/useSamplesDrawer.tsx @@ -3,6 +3,8 @@ import {useCallback} from 'react'; import useDrawer from 'sentry/components/globalDrawer'; import {t} from 'sentry/locale'; import {trackAnalytics} from 'sentry/utils/analytics'; +import {useLocation} from 'sentry/utils/useLocation'; +import {useNavigate} from 'sentry/utils/useNavigate'; import useOrganization from 'sentry/utils/useOrganization'; import type {ModuleName} from '../../types'; @@ -10,16 +12,24 @@ import type {ModuleName} from '../../types'; interface UseSamplesDrawerProps { Component: React.ReactNode; moduleName: ModuleName; - onClose: () => void; } -export function useSamplesDrawer({ - Component, - moduleName, - onClose, -}: UseSamplesDrawerProps) { +export function useSamplesDrawer({Component, moduleName}: UseSamplesDrawerProps) { const organization = useOrganization(); const {openDrawer} = useDrawer(); + const navigate = useNavigate(); + const location = useLocation(); + + const onClose = useCallback(() => { + navigate({ + query: { + ...location.query, + transaction: undefined, + transactionMethod: undefined, + query: undefined, + }, + }); + }, [navigate, location.query]); const openSamplesDrawer = useCallback(() => { trackAnalytics('performance_views.sample_spans.opened', { diff --git a/static/app/views/insights/database/views/databaseSpanSummaryPage.tsx b/static/app/views/insights/database/views/databaseSpanSummaryPage.tsx index 43065066149252..bbbbd7dff1fe03 100644 --- a/static/app/views/insights/database/views/databaseSpanSummaryPage.tsx +++ b/static/app/views/insights/database/views/databaseSpanSummaryPage.tsx @@ -10,7 +10,6 @@ import {DurationUnit, RateUnit} from 'sentry/utils/discover/fields'; import {decodeScalar, decodeSorts} from 'sentry/utils/queryString'; import {MutableSearch} from 'sentry/utils/tokenizeSearch'; import {useLocation} from 'sentry/utils/useLocation'; -import {useNavigate} from 'sentry/utils/useNavigate'; import {useSynchronizeCharts} from 'sentry/views/insights/common/components/chart'; import {HeaderContainer} from 'sentry/views/insights/common/components/headerContainer'; import InsightIssuesList from 'sentry/views/insights/common/components/issues'; @@ -150,8 +149,6 @@ export function DatabaseSpanSummaryPage({params}: Props) { [SpanMetricsField.SPAN_GROUP]: string; }; - const navigate = useNavigate(); - const {openSamplesDrawer} = useSamplesDrawer({ Component: ( ), moduleName: ModuleName.DB, - onClose: () => { - navigate({ - query: { - ...location.query, - transaction: undefined, - transactionMethod: undefined, - }, - }); - }, }); useEffect(() => { diff --git a/static/app/views/insights/http/views/httpDomainSummaryPage.tsx b/static/app/views/insights/http/views/httpDomainSummaryPage.tsx index fc94666062a24c..147957045d8f31 100644 --- a/static/app/views/insights/http/views/httpDomainSummaryPage.tsx +++ b/static/app/views/insights/http/views/httpDomainSummaryPage.tsx @@ -14,7 +14,6 @@ import { } from 'sentry/utils/tokenizeSearch'; import useLocationQuery from 'sentry/utils/url/useLocationQuery'; import {useLocation} from 'sentry/utils/useLocation'; -import {useNavigate} from 'sentry/utils/useNavigate'; import useProjects from 'sentry/utils/useProjects'; import {useSynchronizeCharts} from 'sentry/views/insights/common/components/chart'; import {HeaderContainer} from 'sentry/views/insights/common/components/headerContainer'; @@ -89,20 +88,9 @@ export function HTTPDomainSummaryPage() { }, }); - const navigate = useNavigate(); - const {openSamplesDrawer} = useSamplesDrawer({ Component: , moduleName: ModuleName.HTTP, - onClose: () => { - navigate({ - query: { - ...location.query, - transaction: undefined, - transactionMethod: undefined, - }, - }); - }, }); useEffect(() => { diff --git a/static/app/views/insights/queues/views/destinationSummaryPage.tsx b/static/app/views/insights/queues/views/destinationSummaryPage.tsx index 06a16e1557b490..47d606966f6a6a 100644 --- a/static/app/views/insights/queues/views/destinationSummaryPage.tsx +++ b/static/app/views/insights/queues/views/destinationSummaryPage.tsx @@ -7,7 +7,6 @@ import {space} from 'sentry/styles/space'; import {DurationUnit} from 'sentry/utils/discover/fields'; import {decodeScalar} from 'sentry/utils/queryString'; import {useLocation} from 'sentry/utils/useLocation'; -import {useNavigate} from 'sentry/utils/useNavigate'; import useOrganization from 'sentry/utils/useOrganization'; import {HeaderContainer} from 'sentry/views/insights/common/components/headerContainer'; import {MetricReadout} from 'sentry/views/insights/common/components/metricReadout'; @@ -44,20 +43,9 @@ function DestinationSummaryPage() { }); const errorRate = 1 - (data[0]?.['trace_status_rate(ok)'] ?? 0); - const navigate = useNavigate(); - const {openSamplesDrawer} = useSamplesDrawer({ Component: , moduleName: ModuleName.QUEUE, - onClose: () => { - navigate({ - query: { - ...query, - transaction: undefined, - transactionMethod: undefined, - }, - }); - }, }); useEffect(() => { From c3be7587391088875d5420858134dff72341a3cf Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 09:47:05 -0500 Subject: [PATCH 13/37] Use drawer in Web Vitals --- .../pageOverviewWebVitalsDetailPanel.tsx | 11 ++++--- .../components/webVitalDescription.tsx | 1 - .../components/webVitalsDetailPanel.tsx | 19 ++++------- .../browser/webVitals/views/pageOverview.tsx | 32 ++++++++++++------- .../webVitals/views/webVitalsLandingPage.tsx | 31 +++++++++--------- .../insights/common/utils/useVitalsDrawer.tsx | 30 +++++++++++++++++ 6 files changed, 80 insertions(+), 44 deletions(-) create mode 100644 static/app/views/insights/common/utils/useVitalsDrawer.tsx diff --git a/static/app/views/insights/browser/webVitals/components/pageOverviewWebVitalsDetailPanel.tsx b/static/app/views/insights/browser/webVitals/components/pageOverviewWebVitalsDetailPanel.tsx index 6391caaadb6e95..da1e27eef34426 100644 --- a/static/app/views/insights/browser/webVitals/components/pageOverviewWebVitalsDetailPanel.tsx +++ b/static/app/views/insights/browser/webVitals/components/pageOverviewWebVitalsDetailPanel.tsx @@ -2,6 +2,7 @@ import {useMemo} from 'react'; import styled from '@emotion/styled'; import type {LineChartSeries} from 'sentry/components/charts/lineChart'; +import {DrawerHeader} from 'sentry/components/globalDrawer/components'; import type { GridColumnHeader, GridColumnOrder, @@ -38,7 +39,7 @@ import type { } from 'sentry/views/insights/browser/webVitals/types'; import decodeBrowserTypes from 'sentry/views/insights/browser/webVitals/utils/queryParameterDecoders/browserType'; import useProfileExists from 'sentry/views/insights/browser/webVitals/utils/useProfileExists'; -import DetailPanel from 'sentry/views/insights/common/components/detailPanel'; +import {SampleDrawerBody} from 'sentry/views/insights/common/components/sampleDrawerBody'; import {SpanIndexedField, type SubregionCode} from 'sentry/views/insights/types'; import {TraceViewSources} from 'sentry/views/performance/newTraceDetails/traceHeader/breadcrumbs'; import {generateReplayLink} from 'sentry/views/performance/transactionSummary/utils'; @@ -77,9 +78,7 @@ const inpSort: GridColumnSortBy = { export function PageOverviewWebVitalsDetailPanel({ webVital, - onClose, }: { - onClose: () => void; webVital: WebVitals | null; }) { const location = useLocation(); @@ -367,7 +366,9 @@ export function PageOverviewWebVitalsDetailPanel({ return ( - + + + {webVital && ( - + ); } diff --git a/static/app/views/insights/browser/webVitals/components/webVitalDescription.tsx b/static/app/views/insights/browser/webVitals/components/webVitalDescription.tsx index 4a4d89b1153ec2..ba6923d0d0dce8 100644 --- a/static/app/views/insights/browser/webVitals/components/webVitalDescription.tsx +++ b/static/app/views/insights/browser/webVitals/components/webVitalDescription.tsx @@ -273,7 +273,6 @@ const Value = styled('h2')` const WebVitalName = styled('h4')` margin-bottom: ${space(1)}; - margin-top: 40px; max-width: 400px; ${p => p.theme.overflowEllipsis} `; diff --git a/static/app/views/insights/browser/webVitals/components/webVitalsDetailPanel.tsx b/static/app/views/insights/browser/webVitals/components/webVitalsDetailPanel.tsx index 9cad88eedddd59..195b2336c86038 100644 --- a/static/app/views/insights/browser/webVitals/components/webVitalsDetailPanel.tsx +++ b/static/app/views/insights/browser/webVitals/components/webVitalsDetailPanel.tsx @@ -2,6 +2,7 @@ import {useEffect, useMemo} from 'react'; import styled from '@emotion/styled'; import type {LineChartSeries} from 'sentry/components/charts/lineChart'; +import {DrawerHeader} from 'sentry/components/globalDrawer/components'; import type { GridColumnHeader, GridColumnOrder, @@ -34,7 +35,7 @@ import type { WebVitals, } from 'sentry/views/insights/browser/webVitals/types'; import decodeBrowserTypes from 'sentry/views/insights/browser/webVitals/utils/queryParameterDecoders/browserType'; -import DetailPanel from 'sentry/views/insights/common/components/detailPanel'; +import {SampleDrawerBody} from 'sentry/views/insights/common/components/sampleDrawerBody'; import {SpanIndexedField, type SubregionCode} from 'sentry/views/insights/types'; type Column = GridColumnHeader; @@ -51,13 +52,7 @@ const sort: GridColumnSortBy = {key: 'count()', order: 'desc'}; const MAX_ROWS = 10; -export function WebVitalsDetailPanel({ - webVital, - onClose, -}: { - onClose: () => void; - webVital: WebVitals | null; -}) { +export function WebVitalsDetailPanel({webVital}: {webVital: WebVitals | null}) { const location = useLocation(); const organization = useOrganization(); const browserTypes = decodeBrowserTypes(location.query[SpanIndexedField.BROWSER_NAME]); @@ -133,8 +128,6 @@ export function WebVitalsDetailPanel({ seriesName: webVital ?? '', }; - const detailKey = webVital; - useEffect(() => { if (webVital !== null) { trackAnalytics('insight.vital.vital_sidebar_opened', { @@ -243,7 +236,9 @@ export function WebVitalsDetailPanel({ return ( - + + + {webVital && ( - + ); } diff --git a/static/app/views/insights/browser/webVitals/views/pageOverview.tsx b/static/app/views/insights/browser/webVitals/views/pageOverview.tsx index edf82257080230..a5cd6d45b6da2d 100644 --- a/static/app/views/insights/browser/webVitals/views/pageOverview.tsx +++ b/static/app/views/insights/browser/webVitals/views/pageOverview.tsx @@ -1,4 +1,4 @@ -import React, {Fragment, useMemo, useState} from 'react'; +import React, {Fragment, useEffect, useMemo, useState} from 'react'; import styled from '@emotion/styled'; import omit from 'lodash/omit'; @@ -32,6 +32,7 @@ import {ModulePageFilterBar} from 'sentry/views/insights/common/components/modul import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders'; import {ModuleBodyUpsellHook} from 'sentry/views/insights/common/components/moduleUpsellHookWrapper'; import {useModuleURL} from 'sentry/views/insights/common/utils/useModuleURL'; +import {useVitalsDrawer} from 'sentry/views/insights/common/utils/useVitalsDrawer'; import {FrontendHeader} from 'sentry/views/insights/pages/frontend/frontendPageHeader'; import {useDomainViewFilters} from 'sentry/views/insights/pages/useFilters'; import { @@ -106,6 +107,25 @@ export function PageOverview() { const {data: projectScores, isPending: isProjectScoresLoading} = useProjectWebVitalsScoresQuery({transaction, browserTypes, subregions}); + const {openVitalsDrawer} = useVitalsDrawer({ + Component: , + webVital: state.webVital, + onClose: () => { + router.replace({ + pathname: router.location.pathname, + query: omit(router.location.query, 'webVital'), + }); + + setState({...state, webVital: null}); + }, + }); + + useEffect(() => { + if (state.webVital) { + openVitalsDrawer(); + } + }); + if (transaction === undefined) { // redirect user to webvitals landing page window.location.href = moduleURL; @@ -239,16 +259,6 @@ export function PageOverview() { )} - { - router.replace({ - pathname: router.location.pathname, - query: omit(router.location.query, 'webVital'), - }); - setState({...state, webVital: null}); - }} - /> ); diff --git a/static/app/views/insights/browser/webVitals/views/webVitalsLandingPage.tsx b/static/app/views/insights/browser/webVitals/views/webVitalsLandingPage.tsx index 689e89adcbf2f1..df2aadf7ada984 100644 --- a/static/app/views/insights/browser/webVitals/views/webVitalsLandingPage.tsx +++ b/static/app/views/insights/browser/webVitals/views/webVitalsLandingPage.tsx @@ -1,6 +1,5 @@ -import React, {Fragment, useState} from 'react'; +import React, {Fragment, useEffect, useState} from 'react'; import styled from '@emotion/styled'; -import omit from 'lodash/omit'; import Alert from 'sentry/components/alert'; import {Button} from 'sentry/components/button'; @@ -12,7 +11,6 @@ import {t, tct} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import {decodeList} from 'sentry/utils/queryString'; import {useLocation} from 'sentry/utils/useLocation'; -import useRouter from 'sentry/utils/useRouter'; import BrowserTypeSelector from 'sentry/views/insights/browser/webVitals/components/browserTypeSelector'; import {PerformanceScoreChart} from 'sentry/views/insights/browser/webVitals/components/charts/performanceScoreChart'; import {PagePerformanceTable} from 'sentry/views/insights/browser/webVitals/components/tables/pagePerformanceTable'; @@ -32,6 +30,7 @@ import {ModulePageFilterBar} from 'sentry/views/insights/common/components/modul import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders'; import {ModulesOnboarding} from 'sentry/views/insights/common/components/modulesOnboarding'; import {ModuleBodyUpsellHook} from 'sentry/views/insights/common/components/moduleUpsellHookWrapper'; +import {useVitalsDrawer} from 'sentry/views/insights/common/utils/useVitalsDrawer'; import {FrontendHeader} from 'sentry/views/insights/pages/frontend/frontendPageHeader'; import { ModuleName, @@ -44,8 +43,6 @@ const WEB_VITALS_COUNT = 5; export function WebVitalsLandingPage() { const location = useLocation(); - const router = useRouter(); - const [state, setState] = useState<{webVital: WebVitals | null}>({ webVital: (location.query.webVital as WebVitals) ?? null, }); @@ -67,6 +64,20 @@ export function WebVitalsLandingPage() { ? undefined : getWebVitalScoresFromTableDataRow(projectScores?.data?.[0]); + const {openVitalsDrawer} = useVitalsDrawer({ + Component: , + webVital: state.webVital, + onClose: () => { + setState({webVital: null}); + }, + }); + + useEffect(() => { + if (state.webVital) { + openVitalsDrawer(); + } + }); + return ( - { - router.replace({ - pathname: router.location.pathname, - query: omit(router.location.query, 'webVital'), - }); - setState({...state, webVital: null}); - }} - /> ); } diff --git a/static/app/views/insights/common/utils/useVitalsDrawer.tsx b/static/app/views/insights/common/utils/useVitalsDrawer.tsx new file mode 100644 index 00000000000000..d0df46b147a9a8 --- /dev/null +++ b/static/app/views/insights/common/utils/useVitalsDrawer.tsx @@ -0,0 +1,30 @@ +import {useCallback} from 'react'; + +import useDrawer from 'sentry/components/globalDrawer'; +import {t} from 'sentry/locale'; + +import type {WebVitals} from '../../browser/webVitals/types'; + +interface UseSamplesDrawerProps { + Component: React.ReactNode; + onClose: () => void; + webVital: WebVitals | null; +} + +export function useVitalsDrawer({Component, webVital, onClose}: UseSamplesDrawerProps) { + const {openDrawer} = useDrawer(); + + const openVitalsDrawer = useCallback(() => { + if (!webVital) { + return; + } + + openDrawer(() => Component, { + ariaLabel: t('%s Details', webVital), + onClose, + transitionProps: {stiffness: 1000}, + }); + }, [openDrawer, onClose, Component, webVital]); + + return {openVitalsDrawer}; +} From f5e81795926119924cfbe85fca20d47372bc133a Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 10:17:29 -0500 Subject: [PATCH 14/37] Give vitals drawer a more specific name --- .../views/insights/browser/webVitals/views/pageOverview.tsx | 4 ++-- .../browser/webVitals/views/webVitalsLandingPage.tsx | 4 ++-- .../utils/{useVitalsDrawer.tsx => useWebVitalsDrawer.tsx} | 6 +++++- 3 files changed, 9 insertions(+), 5 deletions(-) rename static/app/views/insights/common/utils/{useVitalsDrawer.tsx => useWebVitalsDrawer.tsx} (86%) diff --git a/static/app/views/insights/browser/webVitals/views/pageOverview.tsx b/static/app/views/insights/browser/webVitals/views/pageOverview.tsx index a5cd6d45b6da2d..a2027d26c0e96b 100644 --- a/static/app/views/insights/browser/webVitals/views/pageOverview.tsx +++ b/static/app/views/insights/browser/webVitals/views/pageOverview.tsx @@ -32,7 +32,7 @@ import {ModulePageFilterBar} from 'sentry/views/insights/common/components/modul import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders'; import {ModuleBodyUpsellHook} from 'sentry/views/insights/common/components/moduleUpsellHookWrapper'; import {useModuleURL} from 'sentry/views/insights/common/utils/useModuleURL'; -import {useVitalsDrawer} from 'sentry/views/insights/common/utils/useVitalsDrawer'; +import {useWebVitalsDrawer} from 'sentry/views/insights/common/utils/useWebVitalsDrawer'; import {FrontendHeader} from 'sentry/views/insights/pages/frontend/frontendPageHeader'; import {useDomainViewFilters} from 'sentry/views/insights/pages/useFilters'; import { @@ -107,7 +107,7 @@ export function PageOverview() { const {data: projectScores, isPending: isProjectScoresLoading} = useProjectWebVitalsScoresQuery({transaction, browserTypes, subregions}); - const {openVitalsDrawer} = useVitalsDrawer({ + const {openVitalsDrawer} = useWebVitalsDrawer({ Component: , webVital: state.webVital, onClose: () => { diff --git a/static/app/views/insights/browser/webVitals/views/webVitalsLandingPage.tsx b/static/app/views/insights/browser/webVitals/views/webVitalsLandingPage.tsx index df2aadf7ada984..370759d871f12e 100644 --- a/static/app/views/insights/browser/webVitals/views/webVitalsLandingPage.tsx +++ b/static/app/views/insights/browser/webVitals/views/webVitalsLandingPage.tsx @@ -30,7 +30,7 @@ import {ModulePageFilterBar} from 'sentry/views/insights/common/components/modul import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders'; import {ModulesOnboarding} from 'sentry/views/insights/common/components/modulesOnboarding'; import {ModuleBodyUpsellHook} from 'sentry/views/insights/common/components/moduleUpsellHookWrapper'; -import {useVitalsDrawer} from 'sentry/views/insights/common/utils/useVitalsDrawer'; +import {useWebVitalsDrawer} from 'sentry/views/insights/common/utils/useWebVitalsDrawer'; import {FrontendHeader} from 'sentry/views/insights/pages/frontend/frontendPageHeader'; import { ModuleName, @@ -64,7 +64,7 @@ export function WebVitalsLandingPage() { ? undefined : getWebVitalScoresFromTableDataRow(projectScores?.data?.[0]); - const {openVitalsDrawer} = useVitalsDrawer({ + const {openVitalsDrawer} = useWebVitalsDrawer({ Component: , webVital: state.webVital, onClose: () => { diff --git a/static/app/views/insights/common/utils/useVitalsDrawer.tsx b/static/app/views/insights/common/utils/useWebVitalsDrawer.tsx similarity index 86% rename from static/app/views/insights/common/utils/useVitalsDrawer.tsx rename to static/app/views/insights/common/utils/useWebVitalsDrawer.tsx index d0df46b147a9a8..1fca1d7e896467 100644 --- a/static/app/views/insights/common/utils/useVitalsDrawer.tsx +++ b/static/app/views/insights/common/utils/useWebVitalsDrawer.tsx @@ -11,7 +11,11 @@ interface UseSamplesDrawerProps { webVital: WebVitals | null; } -export function useVitalsDrawer({Component, webVital, onClose}: UseSamplesDrawerProps) { +export function useWebVitalsDrawer({ + Component, + webVital, + onClose, +}: UseSamplesDrawerProps) { const {openDrawer} = useDrawer(); const openVitalsDrawer = useCallback(() => { From 69908e084fcac15187f89959835cd696c840d4d6 Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 10:17:51 -0500 Subject: [PATCH 15/37] Omit more span properties from URL on close --- static/app/views/insights/common/utils/useSamplesDrawer.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/static/app/views/insights/common/utils/useSamplesDrawer.tsx b/static/app/views/insights/common/utils/useSamplesDrawer.tsx index ddc0820e3fa058..6daa26a073eeaf 100644 --- a/static/app/views/insights/common/utils/useSamplesDrawer.tsx +++ b/static/app/views/insights/common/utils/useSamplesDrawer.tsx @@ -26,6 +26,8 @@ export function useSamplesDrawer({Component, moduleName}: UseSamplesDrawerProps) ...location.query, transaction: undefined, transactionMethod: undefined, + spanGroup: undefined, + spanOp: undefined, query: undefined, }, }); From 2d031f15a9be9ae6ae38b1570819be8059f7c02d Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 10:52:23 -0500 Subject: [PATCH 16/37] Use drawer in Mobile --- .../common/utils/useMobileVitalsDrawer.tsx | 34 ++++++++++ .../appStarts/views/screenSummaryPage.tsx | 67 +++++++++++-------- .../common/components/spanSamplesPanel.tsx | 43 ++---------- .../screenload/views/screenLoadSpansPage.tsx | 38 ++++++----- .../components/vitalDetailPanel.spec.tsx | 4 +- .../screens/components/vitalDetailPanel.tsx | 12 ++-- .../screens/views/screensLandingPage.tsx | 24 ++++--- .../mobile/ui/views/screenSummaryPage.tsx | 53 +++++++-------- 8 files changed, 147 insertions(+), 128 deletions(-) create mode 100644 static/app/views/insights/common/utils/useMobileVitalsDrawer.tsx diff --git a/static/app/views/insights/common/utils/useMobileVitalsDrawer.tsx b/static/app/views/insights/common/utils/useMobileVitalsDrawer.tsx new file mode 100644 index 00000000000000..364d9fbe33cf6c --- /dev/null +++ b/static/app/views/insights/common/utils/useMobileVitalsDrawer.tsx @@ -0,0 +1,34 @@ +import {useCallback} from 'react'; + +import useDrawer from 'sentry/components/globalDrawer'; +import {t} from 'sentry/locale'; + +import type {VitalItem} from '../../mobile/screens/utils'; + +interface UseMobileVitalsDrawerProps { + Component: React.ReactNode; + onClose: () => void; + vital?: VitalItem; +} + +export function useMobileVitalsDrawer({ + Component, + vital, + onClose, +}: UseMobileVitalsDrawerProps) { + const {openDrawer} = useDrawer(); + + const openVitalsDrawer = useCallback(() => { + if (!vital) { + return; + } + + openDrawer(() => Component, { + ariaLabel: t('%s Details', vital.title), + onClose, + transitionProps: {stiffness: 1000}, + }); + }, [openDrawer, onClose, Component, vital]); + + return {openVitalsDrawer}; +} diff --git a/static/app/views/insights/mobile/appStarts/views/screenSummaryPage.tsx b/static/app/views/insights/mobile/appStarts/views/screenSummaryPage.tsx index e158ca516e3bbb..39d1dfc865ee10 100644 --- a/static/app/views/insights/mobile/appStarts/views/screenSummaryPage.tsx +++ b/static/app/views/insights/mobile/appStarts/views/screenSummaryPage.tsx @@ -21,6 +21,7 @@ import { SECONDARY_RELEASE_ALIAS, } from 'sentry/views/insights/common/components/releaseSelector'; import {ToolRibbon} from 'sentry/views/insights/common/components/ribbon'; +import {useSamplesDrawer} from 'sentry/views/insights/common/utils/useSamplesDrawer'; import {SamplesTables} from 'sentry/views/insights/mobile/appStarts/components/samples'; import { COLD_START_TYPE, @@ -110,6 +111,44 @@ export function ScreenSummaryContentPage() { } }, [location, appStartType, navigate]); + const {openSamplesDrawer} = useSamplesDrawer({ + Component: ( + { + navigate( + { + pathname: location.pathname, + query: omit( + location.query, + 'spanGroup', + 'transactionMethod', + 'spanDescription', + 'spanOp' + ), + }, + {replace: true} + ); + }} + /> + ), + moduleName: ModuleName.SCREEN_RENDERING, + }); + + useEffect(() => { + if (transactionName && spanGroup && spanOp && appStartType) { + openSamplesDrawer(); + } + }); + return ( @@ -181,34 +220,6 @@ export function ScreenSummaryContentPage() { - {spanGroup && spanOp && appStartType && ( - { - navigate( - { - pathname: location.pathname, - query: omit( - location.query, - 'spanGroup', - 'transactionMethod', - 'spanDescription', - 'spanOp' - ), - }, - {replace: true} - ); - }} - /> - )} ); } diff --git a/static/app/views/insights/mobile/common/components/spanSamplesPanel.tsx b/static/app/views/insights/mobile/common/components/spanSamplesPanel.tsx index c43fcea78b5473..e1fae719ee5507 100644 --- a/static/app/views/insights/mobile/common/components/spanSamplesPanel.tsx +++ b/static/app/views/insights/mobile/common/components/spanSamplesPanel.tsx @@ -1,19 +1,16 @@ -import {useCallback} from 'react'; import styled from '@emotion/styled'; -import omit from 'lodash/omit'; import * as qs from 'query-string'; import ProjectAvatar from 'sentry/components/avatar/projectAvatar'; +import {DrawerHeader} from 'sentry/components/globalDrawer/components'; import Link from 'sentry/components/links/link'; import {t} from 'sentry/locale'; import {space} from 'sentry/styles/space'; -import {trackAnalytics} from 'sentry/utils/analytics'; import {PageAlert, PageAlertProvider} from 'sentry/utils/performance/contexts/pageAlert'; import normalizeUrl from 'sentry/utils/url/normalizeUrl'; import {useLocation} from 'sentry/utils/useLocation'; import useOrganization from 'sentry/utils/useOrganization'; -import useRouter from 'sentry/utils/useRouter'; -import DetailPanel from 'sentry/views/insights/common/components/detailPanel'; +import {SampleDrawerBody} from 'sentry/views/insights/common/components/sampleDrawerBody'; import {useReleaseSelection} from 'sentry/views/insights/common/queries/useReleases'; import {SpanSamplesContainer} from 'sentry/views/insights/mobile/common/components/spanSamplesPanelContainer'; import useCrossPlatformProject from 'sentry/views/insights/mobile/common/queries/useCrossPlatformProject'; @@ -42,12 +39,10 @@ export function SpanSamplesPanel({ transactionName, transactionMethod, spanDescription, - onClose, transactionRoute, spanOp, additionalFilters, }: Props) { - const router = useRouter(); const organization = useOrganization(); const {view} = useDomainViewFilters(); @@ -55,24 +50,9 @@ export function SpanSamplesPanel({ const {primaryRelease, secondaryRelease} = useReleaseSelection(); - // A a transaction name is required to show the panel, but a transaction - // method is not - const detailKey = transactionName - ? [groupId, transactionName, transactionMethod].filter(Boolean).join(':') - : undefined; - const {query} = useLocation(); const {project} = useCrossPlatformProject(); - const onOpenDetailPanel = useCallback(() => { - if (query.transaction) { - trackAnalytics('performance_views.sample_spans.opened', { - organization, - source: moduleName, - }); - } - }, [organization, query.transaction, moduleName]); - const label = transactionMethod && !transactionName.startsWith(transactionMethod) ? `${transactionMethod} ${transactionName}` @@ -85,22 +65,11 @@ export function SpanSamplesPanel({ })}` ); - function defaultOnClose() { - router.replace({ - pathname: router.location.pathname, - query: omit(router.location.query, 'transaction', 'transactionMethod'), - }); - } - return ( - { - onClose ? onClose() : defaultOnClose(); - }} - onOpen={onOpenDetailPanel} - > + + + {project && ( - + ); } diff --git a/static/app/views/insights/mobile/screenload/views/screenLoadSpansPage.tsx b/static/app/views/insights/mobile/screenload/views/screenLoadSpansPage.tsx index 36b4db1bc1a8ef..ad1c70c2abaa73 100644 --- a/static/app/views/insights/mobile/screenload/views/screenLoadSpansPage.tsx +++ b/static/app/views/insights/mobile/screenload/views/screenLoadSpansPage.tsx @@ -1,6 +1,5 @@ -import {Fragment} from 'react'; +import {Fragment, useEffect} from 'react'; import styled from '@emotion/styled'; -import omit from 'lodash/omit'; import ErrorBoundary from 'sentry/components/errorBoundary'; import * as Layout from 'sentry/components/layouts/thirds'; @@ -10,7 +9,6 @@ import {DurationUnit} from 'sentry/utils/discover/fields'; import {DiscoverDatasets} from 'sentry/utils/discover/types'; import {PageAlert, PageAlertProvider} from 'sentry/utils/performance/contexts/pageAlert'; import {useLocation} from 'sentry/utils/useLocation'; -import useRouter from 'sentry/utils/useRouter'; import {HeaderContainer} from 'sentry/views/insights/common/components/headerContainer'; import {ModulePageFilterBar} from 'sentry/views/insights/common/components/modulePageFilterBar'; import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders'; @@ -20,6 +18,7 @@ import { SECONDARY_RELEASE_ALIAS, } from 'sentry/views/insights/common/components/releaseSelector'; import {ToolRibbon} from 'sentry/views/insights/common/components/ribbon'; +import {useSamplesDrawer} from 'sentry/views/insights/common/utils/useSamplesDrawer'; import {QueryParameterNames} from 'sentry/views/insights/common/views/queryParameters'; import {SpanSamplesPanel} from 'sentry/views/insights/mobile/common/components/spanSamplesPanel'; import useCrossPlatformProject from 'sentry/views/insights/mobile/common/queries/useCrossPlatformProject'; @@ -79,7 +78,6 @@ function ScreenLoadSpans() { export function ScreenLoadSpansContent() { const location = useLocation(); - const router = useRouter(); const { spanGroup, @@ -89,6 +87,24 @@ export function ScreenLoadSpansContent() { spanDescription, } = location.query; + const {openSamplesDrawer} = useSamplesDrawer({ + Component: ( + + ), + moduleName: ModuleName.SCREEN_LOAD, + }); + + useEffect(() => { + if (transactionName && spanGroup) { + openSamplesDrawer(); + } + }); + return ( @@ -180,20 +196,6 @@ export function ScreenLoadSpansContent() { primaryRelease={primaryRelease} secondaryRelease={secondaryRelease} /> - {spanGroup && ( - { - router.replace({ - pathname: router.location.pathname, - query: omit(router.location.query, 'spanGroup', 'transactionMethod'), - }); - }} - /> - )} ); diff --git a/static/app/views/insights/mobile/screens/components/vitalDetailPanel.spec.tsx b/static/app/views/insights/mobile/screens/components/vitalDetailPanel.spec.tsx index 6fd3c2a3b03440..eadc087f9dd885 100644 --- a/static/app/views/insights/mobile/screens/components/vitalDetailPanel.spec.tsx +++ b/static/app/views/insights/mobile/screens/components/vitalDetailPanel.spec.tsx @@ -46,7 +46,7 @@ describe('VitalDetailPanel', () => { test('renders correctly with given props', () => { render( - + ); @@ -69,7 +69,7 @@ describe('VitalDetailPanel', () => { const onCloseMock = jest.fn(); render( - + ); diff --git a/static/app/views/insights/mobile/screens/components/vitalDetailPanel.tsx b/static/app/views/insights/mobile/screens/components/vitalDetailPanel.tsx index 6ae37bf48a96cf..ba2f939aa4621f 100644 --- a/static/app/views/insights/mobile/screens/components/vitalDetailPanel.tsx +++ b/static/app/views/insights/mobile/screens/components/vitalDetailPanel.tsx @@ -1,12 +1,13 @@ import React from 'react'; import styled from '@emotion/styled'; +import {DrawerHeader} from 'sentry/components/globalDrawer/components'; import ExternalLink from 'sentry/components/links/externalLink'; import {t} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import {PageAlert, PageAlertProvider} from 'sentry/utils/performance/contexts/pageAlert'; import {PERFORMANCE_SCORE_COLORS} from 'sentry/views/insights/browser/webVitals/utils/performanceScoreColors'; -import DetailPanel from 'sentry/views/insights/common/components/detailPanel'; +import {SampleDrawerBody} from 'sentry/views/insights/common/components/sampleDrawerBody'; import useCrossPlatformProject from 'sentry/views/insights/mobile/common/queries/useCrossPlatformProject'; import { PerformanceScore, @@ -17,9 +18,7 @@ import { export function VitalDetailPanel({ vital, status, - onClose, }: { - onClose: () => void; status: VitalStatus | undefined; vital: VitalItem | undefined; }) { @@ -30,7 +29,9 @@ export function VitalDetailPanel({ return ( - + + + {vital && ( {vital.title} @@ -68,14 +69,13 @@ export function VitalDetailPanel({ )} - + ); } const VitalDetailTitle = styled('h4')` margin-bottom: ${space(1)}; - margin-top: 40px; `; const Badge = styled('div')<{status: string}>` diff --git a/static/app/views/insights/mobile/screens/views/screensLandingPage.tsx b/static/app/views/insights/mobile/screens/views/screensLandingPage.tsx index c4a806c334f592..2cac04d3100870 100644 --- a/static/app/views/insights/mobile/screens/views/screensLandingPage.tsx +++ b/static/app/views/insights/mobile/screens/views/screensLandingPage.tsx @@ -1,4 +1,4 @@ -import {Fragment, useCallback, useState} from 'react'; +import {Fragment, useCallback, useEffect, useState} from 'react'; import styled from '@emotion/styled'; import omit from 'lodash/omit'; @@ -24,6 +24,7 @@ import useOrganization from 'sentry/utils/useOrganization'; import usePageFilters from 'sentry/utils/usePageFilters'; import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders'; import {ModuleBodyUpsellHook} from 'sentry/views/insights/common/components/moduleUpsellHookWrapper'; +import {useMobileVitalsDrawer} from 'sentry/views/insights/common/utils/useMobileVitalsDrawer'; import useCrossPlatformProject from 'sentry/views/insights/mobile/common/queries/useCrossPlatformProject'; import {PlatformSelector} from 'sentry/views/insights/mobile/screenload/components/platformSelector'; import {SETUP_CONTENT as TTFD_SETUP} from 'sentry/views/insights/mobile/screenload/data/setupContent'; @@ -287,6 +288,20 @@ export function ScreensLandingPage() { return undefined; }; + const {openVitalsDrawer} = useMobileVitalsDrawer({ + Component: , + vital: state.vital, + onClose: () => { + setState({vital: undefined, status: undefined}); + }, + }); + + useEffect(() => { + if (state.vital) { + openVitalsDrawer(); + } + }); + return ( @@ -347,13 +362,6 @@ export function ScreensLandingPage() { - { - setState({vital: undefined, status: undefined}); - }} - /> diff --git a/static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx b/static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx index bbfdce2991a620..778c7dacc37251 100644 --- a/static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx +++ b/static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx @@ -1,6 +1,5 @@ -import {Fragment} from 'react'; +import {Fragment, useEffect} from 'react'; import styled from '@emotion/styled'; -import omit from 'lodash/omit'; import * as Layout from 'sentry/components/layouts/thirds'; import {t} from 'sentry/locale'; @@ -8,12 +7,12 @@ import {space} from 'sentry/styles/space'; import {PageAlert, PageAlertProvider} from 'sentry/utils/performance/contexts/pageAlert'; import {useLocation} from 'sentry/utils/useLocation'; import useOrganization from 'sentry/utils/useOrganization'; -import useRouter from 'sentry/utils/useRouter'; import {HeaderContainer} from 'sentry/views/insights/common/components/headerContainer'; import {ModulePageFilterBar} from 'sentry/views/insights/common/components/modulePageFilterBar'; import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders'; import {ReleaseComparisonSelector} from 'sentry/views/insights/common/components/releaseSelector'; import {ToolRibbon} from 'sentry/views/insights/common/components/ribbon'; +import {useSamplesDrawer} from 'sentry/views/insights/common/utils/useSamplesDrawer'; import {SpanSamplesPanel} from 'sentry/views/insights/mobile/common/components/spanSamplesPanel'; import {SamplesTables} from 'sentry/views/insights/mobile/common/components/tables/samplesTables'; import {SpanOperationTable} from 'sentry/views/insights/mobile/ui/components/tables/spanOperationTable'; @@ -65,7 +64,6 @@ function ScreenSummary() { export function ScreenSummaryContent() { const location = useLocation(); - const router = useRouter(); const { transaction: transactionName, @@ -75,6 +73,28 @@ export function ScreenSummaryContent() { 'device.class': deviceClass, } = location.query; + const {openSamplesDrawer} = useSamplesDrawer({ + Component: ( + + ), + moduleName: ModuleName.SCREEN_RENDERING, + }); + + useEffect(() => { + if (spanGroup && spanOp) { + openSamplesDrawer(); + } + }); + return ( @@ -95,31 +115,6 @@ export function ScreenSummaryContent() { EventSamples={_props =>
} /> - - {spanGroup && spanOp && ( - { - router.replace({ - pathname: router.location.pathname, - query: omit( - router.location.query, - 'spanGroup', - 'transactionMethod', - 'spanDescription', - 'spanOp' - ), - }); - }} - /> - )} ); } From ec734d8c2b4bae2edf81b8a9c1206f32ffbdb5f5 Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 10:55:14 -0500 Subject: [PATCH 17/37] Fold me into rename --- .../common/components/sampleDrawerHeaderTransaction.spec.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.spec.tsx b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.spec.tsx index fd062a11554135..6506211f5a9704 100644 --- a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.spec.tsx +++ b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.spec.tsx @@ -2,7 +2,7 @@ import {ProjectFixture} from 'sentry-fixture/project'; import {render, screen} from 'sentry-test/reactTestingLibrary'; -import {SampleDrawerHeaderTransaction} from './sampleDrawerHeader'; +import {SampleDrawerHeaderTransaction} from './sampleDrawerHeaderTransaction'; describe('SampleDrawerHeaderTransaction', () => { it('Links to the transaction summary page', () => { From a746b401ed26a2b21ea14e5647239a4d0a9fc161 Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:26:02 -0500 Subject: [PATCH 18/37] Project is optional for rendering the drawer header --- .../sampleDrawerHeaderTransaction.tsx | 57 ++++++++++++------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx index 200154efc290f2..df078490f3ae42 100644 --- a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx +++ b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx @@ -11,8 +11,8 @@ import {getTransactionSummaryBaseUrl} from 'sentry/views/performance/transaction import {useDomainViewFilters} from '../../pages/useFilters'; interface SampleDrawerHeaderProps { - project: Project; transaction: string; + project?: Project; transactionMethod?: string; } @@ -22,29 +22,38 @@ export function SampleDrawerHeaderTransaction(props: SampleDrawerHeaderProps) { const {project, transaction, transactionMethod} = props; const {view} = useDomainViewFilters(); + const label = + transaction && transactionMethod && !transaction.startsWith(transactionMethod) + ? `${transactionMethod} ${transaction}` + : transaction; + return ( - - - - {transaction && transactionMethod && !transaction.startsWith(transactionMethod) - ? `${transactionMethod} ${transaction}` - : transaction} - + {project && ( + + )} + + {project ? ( + + {label} + + ) : ( + {label} + )} ); } @@ -58,3 +67,7 @@ const Bar = styled('div')` const TruncatedLink = styled(Link)` ${p => p.theme.overflowEllipsis} `; + +const TruncatedSpan = styled('span')` + ${p => p.theme.overflowEllipsis} +`; From 532748dc5894a91c20e6c6236b02b79e7d52d3b7 Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:26:24 -0500 Subject: [PATCH 19/37] Use heading for header This is what the tests expect, and it makes sense --- .../common/components/sampleDrawerHeaderTransaction.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx index df078490f3ae42..bf5991cd94c8b3 100644 --- a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx +++ b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx @@ -58,10 +58,15 @@ export function SampleDrawerHeaderTransaction(props: SampleDrawerHeaderProps) { ); } -const Bar = styled('div')` +const Bar = styled('h4')` display: flex; align-items: center; gap: ${space(1)}; + padding: 0; + margin: 0; + + font-size: ${p => p.theme.fontSizeMedium}; + font-weight: ${p => p.theme.fontWeightNormal}; `; const TruncatedLink = styled(Link)` From be1647b9e73a604d50f3fc89c5f8155e762e6450 Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:26:58 -0500 Subject: [PATCH 20/37] Do not gate header behind project It's optional now --- .../views/insights/cache/components/samplePanel.tsx | 10 ++++------ .../views/spanSummaryPage/sampleList/index.tsx | 12 +++++------- .../insights/http/components/httpSamplesPanel.tsx | 12 +++++------- .../queues/components/messageSpanSamplesPanel.tsx | 10 ++++------ 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/static/app/views/insights/cache/components/samplePanel.tsx b/static/app/views/insights/cache/components/samplePanel.tsx index d404f35033b49f..fc5fcfcf4c6fed 100644 --- a/static/app/views/insights/cache/components/samplePanel.tsx +++ b/static/app/views/insights/cache/components/samplePanel.tsx @@ -241,12 +241,10 @@ export function CacheSamplePanel() { return ( - {project && ( - - )} + diff --git a/static/app/views/insights/common/views/spanSummaryPage/sampleList/index.tsx b/static/app/views/insights/common/views/spanSummaryPage/sampleList/index.tsx index be6703cfafbc5b..df56fa09a78126 100644 --- a/static/app/views/insights/common/views/spanSummaryPage/sampleList/index.tsx +++ b/static/app/views/insights/common/views/spanSummaryPage/sampleList/index.tsx @@ -132,13 +132,11 @@ export function SampleList({ return ( - {project && ( - - )} + diff --git a/static/app/views/insights/http/components/httpSamplesPanel.tsx b/static/app/views/insights/http/components/httpSamplesPanel.tsx index 28f967d576ee20..70d9e14c21cab4 100644 --- a/static/app/views/insights/http/components/httpSamplesPanel.tsx +++ b/static/app/views/insights/http/components/httpSamplesPanel.tsx @@ -293,13 +293,11 @@ export function HTTPSamplesPanel() { return ( - {project && ( - - )} + diff --git a/static/app/views/insights/queues/components/messageSpanSamplesPanel.tsx b/static/app/views/insights/queues/components/messageSpanSamplesPanel.tsx index 38080a3fd51c07..643904abfa4c3f 100644 --- a/static/app/views/insights/queues/components/messageSpanSamplesPanel.tsx +++ b/static/app/views/insights/queues/components/messageSpanSamplesPanel.tsx @@ -226,12 +226,10 @@ export function MessageSpanSamplesPanel() { return ( - {project && ( - - )} + From 27cf16148e6f71f6b3c6c324d5b45dc15ec84ffc Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:27:14 -0500 Subject: [PATCH 21/37] Fix data loading in cache panel --- .../insights/cache/components/samplePanel.tsx | 10 -------- .../cache/views/cacheLandingPage.spec.tsx | 23 ------------------- 2 files changed, 33 deletions(-) diff --git a/static/app/views/insights/cache/components/samplePanel.tsx b/static/app/views/insights/cache/components/samplePanel.tsx index fc5fcfcf4c6fed..1a83b52b61bf1b 100644 --- a/static/app/views/insights/cache/components/samplePanel.tsx +++ b/static/app/views/insights/cache/components/samplePanel.tsx @@ -92,13 +92,6 @@ export function CacheSamplePanel() { }); }; - // `detailKey` controls whether the panel is open. If all required properties are ailable, concat them to make a key, otherwise set to `undefined` and hide the panel - const detailKey = query.transaction - ? [query.transaction].filter(Boolean).join(':') - : undefined; - - const isPanelOpen = Boolean(detailKey); - const filters: SpanMetricsQueryFilters = { ...BASE_FILTERS, transaction: query.transaction, @@ -124,7 +117,6 @@ export function CacheSamplePanel() { `sum(${SpanMetricsField.SPAN_SELF_TIME})`, `avg(${SpanMetricsField.CACHE_ITEM_SIZE})`, ], - enabled: isPanelOpen, }, Referrer.SAMPLES_CACHE_METRICS_RIBBON ); @@ -136,7 +128,6 @@ export function CacheSamplePanel() { transaction: query.transaction, } satisfies MetricsQueryFilters), fields: [`avg(${MetricsFields.TRANSACTION_DURATION})`], - enabled: isPanelOpen && Boolean(query.transaction), }, Referrer.SAMPLES_CACHE_TRANSACTION_DURATION ); @@ -171,7 +162,6 @@ export function CacheSamplePanel() { ], sorts: [SPAN_SAMPLES_SORT], limit, - enabled: isPanelOpen, }, Referrer.SAMPLES_CACHE_SPAN_SAMPLES ); diff --git a/static/app/views/insights/cache/views/cacheLandingPage.spec.tsx b/static/app/views/insights/cache/views/cacheLandingPage.spec.tsx index ccfc9f03d685ff..bb42a27f484dad 100644 --- a/static/app/views/insights/cache/views/cacheLandingPage.spec.tsx +++ b/static/app/views/insights/cache/views/cacheLandingPage.spec.tsx @@ -93,29 +93,6 @@ describe('CacheLandingPage', function () { await waitForElementToBeRemoved(() => screen.queryAllByTestId('loading-indicator')); - expect(requestMocks.missRateChart).toHaveBeenCalledWith( - `/organizations/${organization.slug}/events-stats/`, - expect.objectContaining({ - method: 'GET', - query: { - cursor: undefined, - dataset: 'spansMetrics', - environment: [], - excludeOther: 0, - field: [], - interval: '30m', - orderby: undefined, - partial: 1, - per_page: 50, - project: [], - query: 'span.op:[cache.get_item,cache.get] project.id:1', - referrer: 'api.performance.cache.samples-cache-hit-miss-chart', - statsPeriod: '10d', - topEvents: undefined, - yAxis: 'cache_miss_rate()', - }, - }) - ); expect(requestMocks.throughputChart).toHaveBeenCalledWith( `/organizations/${organization.slug}/events-stats/`, expect.objectContaining({ From 3082221afbd10df09514261dbc0060181fe0db5e Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:37:06 -0500 Subject: [PATCH 22/37] Add subtitle support to drawer header --- .../common/components/sampleDrawerHeaderTransaction.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx index bf5991cd94c8b3..c1c3dae4a02da3 100644 --- a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx +++ b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx @@ -13,13 +13,14 @@ import {useDomainViewFilters} from '../../pages/useFilters'; interface SampleDrawerHeaderProps { transaction: string; project?: Project; + subtitle?: string; transactionMethod?: string; } export function SampleDrawerHeaderTransaction(props: SampleDrawerHeaderProps) { const organization = useOrganization(); - const {project, transaction, transactionMethod} = props; + const {project, subtitle, transaction, transactionMethod} = props; const {view} = useDomainViewFilters(); const label = @@ -39,6 +40,8 @@ export function SampleDrawerHeaderTransaction(props: SampleDrawerHeaderProps) { /> )} + {subtitle ? {subtitle} : null} + {project ? ( p.theme.fontWeightNormal}; `; +const Subtitle = styled('span')` + color: ${p => p.theme.subText}; +`; + const TruncatedLink = styled(Link)` ${p => p.theme.overflowEllipsis} `; From 37b8e15279d420e9ac295cd54dc3de70bce4e2e5 Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:37:36 -0500 Subject: [PATCH 23/37] Add subtitle to queue panels --- .../insights/queues/components/messageSpanSamplesPanel.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/static/app/views/insights/queues/components/messageSpanSamplesPanel.tsx b/static/app/views/insights/queues/components/messageSpanSamplesPanel.tsx index 643904abfa4c3f..54c474ca4e0e19 100644 --- a/static/app/views/insights/queues/components/messageSpanSamplesPanel.tsx +++ b/static/app/views/insights/queues/components/messageSpanSamplesPanel.tsx @@ -229,6 +229,9 @@ export function MessageSpanSamplesPanel() { From a367042d14c6bc546f60470d68517ee49c4705cf Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:38:07 -0500 Subject: [PATCH 24/37] Remove unneeded test --- .../screens/components/vitalDetailPanel.spec.tsx | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/static/app/views/insights/mobile/screens/components/vitalDetailPanel.spec.tsx b/static/app/views/insights/mobile/screens/components/vitalDetailPanel.spec.tsx index eadc087f9dd885..bb3a41bff9d667 100644 --- a/static/app/views/insights/mobile/screens/components/vitalDetailPanel.spec.tsx +++ b/static/app/views/insights/mobile/screens/components/vitalDetailPanel.spec.tsx @@ -1,4 +1,4 @@ -import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary'; +import {render, screen} from 'sentry-test/reactTestingLibrary'; import {DiscoverDatasets} from 'sentry/utils/discover/types'; import {PageAlertProvider} from 'sentry/utils/performance/contexts/pageAlert'; @@ -64,17 +64,4 @@ describe('VitalDetailPanel', () => { 'https://example.com/platform-docs' ); }); - - test('calls onClose when close action is triggered', async () => { - const onCloseMock = jest.fn(); - render( - - - - ); - - const closeButton = screen.getByLabelText('Close Details'); - await userEvent.click(closeButton); - expect(onCloseMock).toHaveBeenCalled(); - }); }); From 0c787237568d31404006339dc2b0e4cd06cb2e75 Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:39:29 -0500 Subject: [PATCH 25/37] Rename bad interface --- static/app/views/insights/common/utils/useWebVitalsDrawer.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/app/views/insights/common/utils/useWebVitalsDrawer.tsx b/static/app/views/insights/common/utils/useWebVitalsDrawer.tsx index 1fca1d7e896467..157095d9752771 100644 --- a/static/app/views/insights/common/utils/useWebVitalsDrawer.tsx +++ b/static/app/views/insights/common/utils/useWebVitalsDrawer.tsx @@ -5,7 +5,7 @@ import {t} from 'sentry/locale'; import type {WebVitals} from '../../browser/webVitals/types'; -interface UseSamplesDrawerProps { +interface UseWebVitalsDrawerProps { Component: React.ReactNode; onClose: () => void; webVital: WebVitals | null; @@ -15,7 +15,7 @@ export function useWebVitalsDrawer({ Component, webVital, onClose, -}: UseSamplesDrawerProps) { +}: UseWebVitalsDrawerProps) { const {openDrawer} = useDrawer(); const openVitalsDrawer = useCallback(() => { From 34a1266037d16873137c9affbd7caf5904738dac Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:40:17 -0500 Subject: [PATCH 26/37] Remove unused prop --- .../browser/webVitals/components/webVitalsDetailPanel.spec.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/app/views/insights/browser/webVitals/components/webVitalsDetailPanel.spec.tsx b/static/app/views/insights/browser/webVitals/components/webVitalsDetailPanel.spec.tsx index 5129c77ae406c2..8baa6071b00bf6 100644 --- a/static/app/views/insights/browser/webVitals/components/webVitalsDetailPanel.spec.tsx +++ b/static/app/views/insights/browser/webVitals/components/webVitalsDetailPanel.spec.tsx @@ -58,7 +58,7 @@ describe('WebVitalsDetailPanel', function () { }); it('renders correctly with empty results', async () => { - render( undefined} webVital="lcp" />, { + render(, { organization, }); await waitForElementToBeRemoved(() => screen.queryByTestId('loading-indicator')); From 1befd8b2c3bde2dacf783914afd366095be4e9ed Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:44:55 -0500 Subject: [PATCH 27/37] Fix bad truncations --- .../common/components/sampleDrawerHeaderTransaction.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx index c1c3dae4a02da3..aeae99c9b84320 100644 --- a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx +++ b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx @@ -70,6 +70,8 @@ const Bar = styled('h4')` font-size: ${p => p.theme.fontSizeMedium}; font-weight: ${p => p.theme.fontWeightNormal}; + + overflow: hidden; `; const Subtitle = styled('span')` From 8c01969f53a1e10585c075af8c95ae5c07d70fdd Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 23 Dec 2024 12:03:55 -0500 Subject: [PATCH 28/37] Fix analytics --- .../views/insights/mobile/appStarts/views/screenSummaryPage.tsx | 2 +- static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/static/app/views/insights/mobile/appStarts/views/screenSummaryPage.tsx b/static/app/views/insights/mobile/appStarts/views/screenSummaryPage.tsx index 39d1dfc865ee10..827709ce48a579 100644 --- a/static/app/views/insights/mobile/appStarts/views/screenSummaryPage.tsx +++ b/static/app/views/insights/mobile/appStarts/views/screenSummaryPage.tsx @@ -140,7 +140,7 @@ export function ScreenSummaryContentPage() { }} /> ), - moduleName: ModuleName.SCREEN_RENDERING, + moduleName: ModuleName.APP_START, }); useEffect(() => { diff --git a/static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx b/static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx index 778c7dacc37251..dec31717d08d8c 100644 --- a/static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx +++ b/static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx @@ -86,7 +86,7 @@ export function ScreenSummaryContent() { spanOp={spanOp} /> ), - moduleName: ModuleName.SCREEN_RENDERING, + moduleName: ModuleName.OTHER, }); useEffect(() => { From 882b1dc45c806266100b15d4f0da535dd352c6a7 Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 6 Jan 2025 10:03:35 -0500 Subject: [PATCH 29/37] Rename over-specified component --- .../common/components/sampleDrawerHeaderTransaction.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx index aeae99c9b84320..c9bb099e2b0d14 100644 --- a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx +++ b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx @@ -40,7 +40,7 @@ export function SampleDrawerHeaderTransaction(props: SampleDrawerHeaderProps) { /> )} - {subtitle ? {subtitle} : null} + {subtitle ? {subtitle} : null} {project ? ( p.theme.subText}; +const Deemphasize = styled('span')` + color: ${p => p.theme.gray300}; `; const TruncatedLink = styled(Link)` From e0216fc305f71fa3042942de52623f19f9835ed0 Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Mon, 6 Jan 2025 10:04:12 -0500 Subject: [PATCH 30/37] Add subtitle delimiter --- .../sampleDrawerHeaderTransaction.spec.tsx | 17 +++++++++++++++++ .../sampleDrawerHeaderTransaction.tsx | 9 ++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.spec.tsx b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.spec.tsx index 6506211f5a9704..48d7f4de543c40 100644 --- a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.spec.tsx +++ b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.spec.tsx @@ -1,6 +1,7 @@ import {ProjectFixture} from 'sentry-fixture/project'; import {render, screen} from 'sentry-test/reactTestingLibrary'; +import {textWithMarkupMatcher} from 'sentry-test/utils'; import {SampleDrawerHeaderTransaction} from './sampleDrawerHeaderTransaction'; @@ -47,4 +48,20 @@ describe('SampleDrawerHeaderTransaction', () => { const $link = screen.getByRole('link'); expect($link).toHaveAccessibleName('GET /issues'); }); + + it('Shows a prefix', () => { + const project = ProjectFixture(); + + render( + + ); + + expect( + screen.getByText(textWithMarkupMatcher('Producer:tasks.deliver_mail')) + ).toBeInTheDocument(); + }); }); diff --git a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx index c9bb099e2b0d14..522f184de7a009 100644 --- a/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx +++ b/static/app/views/insights/common/components/sampleDrawerHeaderTransaction.tsx @@ -40,7 +40,12 @@ export function SampleDrawerHeaderTransaction(props: SampleDrawerHeaderProps) { /> )} - {subtitle ? {subtitle} : null} + {subtitle ? ( + + {subtitle} + {DELIMITER} + + ) : null} {project ? ( Date: Mon, 6 Jan 2025 10:18:55 -0500 Subject: [PATCH 31/37] Update specs --- .../queues/components/messageSpanSamplesPanel.spec.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/app/views/insights/queues/components/messageSpanSamplesPanel.spec.tsx b/static/app/views/insights/queues/components/messageSpanSamplesPanel.spec.tsx index a58f04f2c5f47b..f14ec38cebfeac 100644 --- a/static/app/views/insights/queues/components/messageSpanSamplesPanel.spec.tsx +++ b/static/app/views/insights/queues/components/messageSpanSamplesPanel.spec.tsx @@ -223,7 +223,7 @@ describe('messageSpanSamplesPanel', () => { }) ); expect(screen.getByRole('table', {name: 'Span Samples'})).toBeInTheDocument(); - expect(screen.getByText('Consumer')).toBeInTheDocument(); + expect(screen.getByText(/Consumer/)).toBeInTheDocument(); // Metrics Ribbon expect(screen.getByText('Processed')).toBeInTheDocument(); expect(screen.getByText('Error Rate')).toBeInTheDocument(); @@ -318,7 +318,7 @@ describe('messageSpanSamplesPanel', () => { }) ); expect(screen.getByRole('table', {name: 'Span Samples'})).toBeInTheDocument(); - expect(screen.getByText('Producer')).toBeInTheDocument(); + expect(screen.getByText(/Producer/)).toBeInTheDocument(); // Metrics Ribbon expect(screen.getByText('Published')).toBeInTheDocument(); expect(screen.getByText('Error Rate')).toBeInTheDocument(); From 4318294c7a6c13ce87d2bc888b2cb4d3cc06e7af Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Tue, 7 Jan 2025 15:20:51 -0500 Subject: [PATCH 32/37] Avoid repeatedly re-opening the drawer --- .../insights/common/utils/useMobileVitalsDrawer.tsx | 6 +++--- .../views/insights/common/utils/useSamplesDrawer.tsx | 10 +++++++--- .../views/insights/common/utils/useWebVitalsDrawer.tsx | 6 +++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/static/app/views/insights/common/utils/useMobileVitalsDrawer.tsx b/static/app/views/insights/common/utils/useMobileVitalsDrawer.tsx index 364d9fbe33cf6c..5055f4ca14a0fc 100644 --- a/static/app/views/insights/common/utils/useMobileVitalsDrawer.tsx +++ b/static/app/views/insights/common/utils/useMobileVitalsDrawer.tsx @@ -16,10 +16,10 @@ export function useMobileVitalsDrawer({ vital, onClose, }: UseMobileVitalsDrawerProps) { - const {openDrawer} = useDrawer(); + const {openDrawer, isDrawerOpen} = useDrawer(); const openVitalsDrawer = useCallback(() => { - if (!vital) { + if (!vital || isDrawerOpen) { return; } @@ -28,7 +28,7 @@ export function useMobileVitalsDrawer({ onClose, transitionProps: {stiffness: 1000}, }); - }, [openDrawer, onClose, Component, vital]); + }, [openDrawer, isDrawerOpen, onClose, Component, vital]); return {openVitalsDrawer}; } diff --git a/static/app/views/insights/common/utils/useSamplesDrawer.tsx b/static/app/views/insights/common/utils/useSamplesDrawer.tsx index 6daa26a073eeaf..867c8604af355b 100644 --- a/static/app/views/insights/common/utils/useSamplesDrawer.tsx +++ b/static/app/views/insights/common/utils/useSamplesDrawer.tsx @@ -16,7 +16,7 @@ interface UseSamplesDrawerProps { export function useSamplesDrawer({Component, moduleName}: UseSamplesDrawerProps) { const organization = useOrganization(); - const {openDrawer} = useDrawer(); + const {openDrawer, isDrawerOpen} = useDrawer(); const navigate = useNavigate(); const location = useLocation(); @@ -34,6 +34,10 @@ export function useSamplesDrawer({Component, moduleName}: UseSamplesDrawerProps) }, [navigate, location.query]); const openSamplesDrawer = useCallback(() => { + if (isDrawerOpen) { + return; + } + trackAnalytics('performance_views.sample_spans.opened', { organization, source: moduleName, @@ -44,7 +48,7 @@ export function useSamplesDrawer({Component, moduleName}: UseSamplesDrawerProps) onClose, transitionProps: {stiffness: 1000}, }); - }, [openDrawer, onClose, Component, organization, moduleName]); + }, [openDrawer, isDrawerOpen, onClose, Component, organization, moduleName]); - return {openSamplesDrawer}; + return {openSamplesDrawer, isDrawerOpen}; } diff --git a/static/app/views/insights/common/utils/useWebVitalsDrawer.tsx b/static/app/views/insights/common/utils/useWebVitalsDrawer.tsx index 157095d9752771..91dbe451f0a96f 100644 --- a/static/app/views/insights/common/utils/useWebVitalsDrawer.tsx +++ b/static/app/views/insights/common/utils/useWebVitalsDrawer.tsx @@ -16,10 +16,10 @@ export function useWebVitalsDrawer({ webVital, onClose, }: UseWebVitalsDrawerProps) { - const {openDrawer} = useDrawer(); + const {openDrawer, isDrawerOpen} = useDrawer(); const openVitalsDrawer = useCallback(() => { - if (!webVital) { + if (!webVital || isDrawerOpen) { return; } @@ -28,7 +28,7 @@ export function useWebVitalsDrawer({ onClose, transitionProps: {stiffness: 1000}, }); - }, [openDrawer, onClose, Component, webVital]); + }, [openDrawer, isDrawerOpen, onClose, Component, webVital]); return {openVitalsDrawer}; } From afd9d2fde06b1d0aac71149f0e7a392a309a65fc Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Tue, 7 Jan 2025 15:52:00 -0500 Subject: [PATCH 33/37] Use a simpler URL hook rendering model --- .../resources/views/resourceSummaryPage.tsx | 11 ++--- .../insights/cache/views/cacheLandingPage.tsx | 16 +------ .../common/utils/useSamplesDrawer.tsx | 43 ++++++++++++++++--- .../views/databaseSpanSummaryPage.tsx | 11 ++--- .../http/views/httpDomainSummaryPage.tsx | 12 ++---- .../appStarts/views/screenSummaryPage.tsx | 14 +++--- .../screenload/views/screenLoadSpansPage.tsx | 11 ++--- .../mobile/ui/views/screenSummaryPage.tsx | 11 ++--- .../queues/views/destinationSummaryPage.tsx | 11 ++--- 9 files changed, 65 insertions(+), 75 deletions(-) diff --git a/static/app/views/insights/browser/resources/views/resourceSummaryPage.tsx b/static/app/views/insights/browser/resources/views/resourceSummaryPage.tsx index 2971e62beaa5ac..9dcbd8e20ca1a1 100644 --- a/static/app/views/insights/browser/resources/views/resourceSummaryPage.tsx +++ b/static/app/views/insights/browser/resources/views/resourceSummaryPage.tsx @@ -1,4 +1,4 @@ -import React, {useEffect} from 'react'; +import React from 'react'; import * as Layout from 'sentry/components/layouts/thirds'; import {t, tct} from 'sentry/locale'; @@ -49,7 +49,7 @@ function ResourceSummary() { query: {transaction}, } = useLocation(); - const {openSamplesDrawer} = useSamplesDrawer({ + useSamplesDrawer({ Component: ( ), moduleName: ModuleName.RESOURCE, - }); - - useEffect(() => { - if (transaction) { - openSamplesDrawer(); - } + requiredParams: ['transaction'], }); const {data, isPending} = useSpanMetrics( diff --git a/static/app/views/insights/cache/views/cacheLandingPage.tsx b/static/app/views/insights/cache/views/cacheLandingPage.tsx index 4e2079a611901e..f5b142d49fa10f 100644 --- a/static/app/views/insights/cache/views/cacheLandingPage.tsx +++ b/static/app/views/insights/cache/views/cacheLandingPage.tsx @@ -14,7 +14,6 @@ import { } from 'sentry/utils/performance/contexts/pageAlert'; import {decodeScalar, decodeSorts} from 'sentry/utils/queryString'; import {MutableSearch} from 'sentry/utils/tokenizeSearch'; -import useLocationQuery from 'sentry/utils/url/useLocationQuery'; import {useLocation} from 'sentry/utils/useLocation'; import {CacheHitMissChart} from 'sentry/views/insights/cache/components/charts/hitMissChart'; import {ThroughputChart} from 'sentry/views/insights/cache/components/charts/throughputChart'; @@ -74,21 +73,10 @@ export function CacheLandingPage() { const sort = decodeSorts(sortField).filter(isAValidSort).at(0) ?? DEFAULT_SORT; const cursor = decodeScalar(location.query?.[QueryParameterNames.TRANSACTIONS_CURSOR]); - const query = useLocationQuery({ - fields: { - transaction: decodeScalar, - }, - }); - - const {openSamplesDrawer} = useSamplesDrawer({ + useSamplesDrawer({ Component: , moduleName: ModuleName.CACHE, - }); - - useEffect(() => { - if (query.transaction) { - openSamplesDrawer(); - } + requiredParams: ['transaction'], }); const { diff --git a/static/app/views/insights/common/utils/useSamplesDrawer.tsx b/static/app/views/insights/common/utils/useSamplesDrawer.tsx index 867c8604af355b..0f5f41c96a776b 100644 --- a/static/app/views/insights/common/utils/useSamplesDrawer.tsx +++ b/static/app/views/insights/common/utils/useSamplesDrawer.tsx @@ -1,4 +1,5 @@ -import {useCallback} from 'react'; +import {useCallback, useEffect} from 'react'; +import type {Location} from 'history'; import useDrawer from 'sentry/components/globalDrawer'; import {t} from 'sentry/locale'; @@ -12,11 +13,16 @@ import type {ModuleName} from '../../types'; interface UseSamplesDrawerProps { Component: React.ReactNode; moduleName: ModuleName; + requiredParams: [string, ...string[]]; } -export function useSamplesDrawer({Component, moduleName}: UseSamplesDrawerProps) { +export function useSamplesDrawer({ + Component, + moduleName, + requiredParams, +}: UseSamplesDrawerProps): void { const organization = useOrganization(); - const {openDrawer, isDrawerOpen} = useDrawer(); + const {openDrawer, closeDrawer, isDrawerOpen} = useDrawer(); const navigate = useNavigate(); const location = useLocation(); @@ -33,6 +39,13 @@ export function useSamplesDrawer({Component, moduleName}: UseSamplesDrawerProps) }); }, [navigate, location.query]); + const shouldCloseOnLocationChange = useCallback( + (newLocation: Location) => { + return !requiredParams.some(paramName => Boolean(newLocation.query[paramName])); + }, + [requiredParams] + ); + const openSamplesDrawer = useCallback(() => { if (isDrawerOpen) { return; @@ -47,8 +60,28 @@ export function useSamplesDrawer({Component, moduleName}: UseSamplesDrawerProps) ariaLabel: t('Samples'), onClose, transitionProps: {stiffness: 1000}, + shouldCloseOnLocationChange, + shouldCloseOnInteractOutside: () => false, }); - }, [openDrawer, isDrawerOpen, onClose, Component, organization, moduleName]); + }, [ + openDrawer, + isDrawerOpen, + onClose, + shouldCloseOnLocationChange, + Component, + organization, + moduleName, + ]); + + const shouldDrawerOpen = requiredParams.every(paramName => + Boolean(location.query[paramName]) + ); - return {openSamplesDrawer, isDrawerOpen}; + useEffect(() => { + if (shouldDrawerOpen) { + openSamplesDrawer(); + } else { + closeDrawer(); + } + }, [shouldDrawerOpen, openSamplesDrawer, closeDrawer]); } diff --git a/static/app/views/insights/database/views/databaseSpanSummaryPage.tsx b/static/app/views/insights/database/views/databaseSpanSummaryPage.tsx index bbbbd7dff1fe03..0a88ab9dc7a153 100644 --- a/static/app/views/insights/database/views/databaseSpanSummaryPage.tsx +++ b/static/app/views/insights/database/views/databaseSpanSummaryPage.tsx @@ -1,4 +1,4 @@ -import {Fragment, useEffect} from 'react'; +import {Fragment} from 'react'; import styled from '@emotion/styled'; import Feature from 'sentry/components/acl/feature'; @@ -149,7 +149,7 @@ export function DatabaseSpanSummaryPage({params}: Props) { [SpanMetricsField.SPAN_GROUP]: string; }; - const {openSamplesDrawer} = useSamplesDrawer({ + useSamplesDrawer({ Component: ( ), moduleName: ModuleName.DB, - }); - - useEffect(() => { - if (transaction) { - openSamplesDrawer(); - } + requiredParams: ['transaction'], }); const { diff --git a/static/app/views/insights/http/views/httpDomainSummaryPage.tsx b/static/app/views/insights/http/views/httpDomainSummaryPage.tsx index 147957045d8f31..4c6de0f5c56855 100644 --- a/static/app/views/insights/http/views/httpDomainSummaryPage.tsx +++ b/static/app/views/insights/http/views/httpDomainSummaryPage.tsx @@ -1,4 +1,4 @@ -import React, {Fragment, useEffect} from 'react'; +import React, {Fragment} from 'react'; import Alert from 'sentry/components/alert'; import ProjectAvatar from 'sentry/components/avatar/projectAvatar'; @@ -77,7 +77,6 @@ export function HTTPDomainSummaryPage() { const { domain, project: projectId, - transaction, 'user.geo.subregion': subregions, } = useLocationQuery({ fields: { @@ -88,15 +87,10 @@ export function HTTPDomainSummaryPage() { }, }); - const {openSamplesDrawer} = useSamplesDrawer({ + useSamplesDrawer({ Component: , moduleName: ModuleName.HTTP, - }); - - useEffect(() => { - if (transaction) { - openSamplesDrawer(); - } + requiredParams: ['transaction'], }); const project = projects.find(p => projectId === p.id); diff --git a/static/app/views/insights/mobile/appStarts/views/screenSummaryPage.tsx b/static/app/views/insights/mobile/appStarts/views/screenSummaryPage.tsx index 827709ce48a579..db55925a5221d6 100644 --- a/static/app/views/insights/mobile/appStarts/views/screenSummaryPage.tsx +++ b/static/app/views/insights/mobile/appStarts/views/screenSummaryPage.tsx @@ -111,7 +111,7 @@ export function ScreenSummaryContentPage() { } }, [location, appStartType, navigate]); - const {openSamplesDrawer} = useSamplesDrawer({ + useSamplesDrawer({ Component: ( ), moduleName: ModuleName.APP_START, - }); - - useEffect(() => { - if (transactionName && spanGroup && spanOp && appStartType) { - openSamplesDrawer(); - } + requiredParams: [ + 'transaction', + 'spanGroup', + 'spanOp', + SpanMetricsField.APP_START_TYPE, + ], }); return ( diff --git a/static/app/views/insights/mobile/screenload/views/screenLoadSpansPage.tsx b/static/app/views/insights/mobile/screenload/views/screenLoadSpansPage.tsx index ad1c70c2abaa73..a47fde1b388293 100644 --- a/static/app/views/insights/mobile/screenload/views/screenLoadSpansPage.tsx +++ b/static/app/views/insights/mobile/screenload/views/screenLoadSpansPage.tsx @@ -1,4 +1,4 @@ -import {Fragment, useEffect} from 'react'; +import {Fragment} from 'react'; import styled from '@emotion/styled'; import ErrorBoundary from 'sentry/components/errorBoundary'; @@ -87,7 +87,7 @@ export function ScreenLoadSpansContent() { spanDescription, } = location.query; - const {openSamplesDrawer} = useSamplesDrawer({ + useSamplesDrawer({ Component: ( ), moduleName: ModuleName.SCREEN_LOAD, - }); - - useEffect(() => { - if (transactionName && spanGroup) { - openSamplesDrawer(); - } + requiredParams: ['transaction', 'spanGroup'], }); return ( diff --git a/static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx b/static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx index dec31717d08d8c..48154e6bb5039f 100644 --- a/static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx +++ b/static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx @@ -1,4 +1,4 @@ -import {Fragment, useEffect} from 'react'; +import {Fragment} from 'react'; import styled from '@emotion/styled'; import * as Layout from 'sentry/components/layouts/thirds'; @@ -73,7 +73,7 @@ export function ScreenSummaryContent() { 'device.class': deviceClass, } = location.query; - const {openSamplesDrawer} = useSamplesDrawer({ + useSamplesDrawer({ Component: ( ), moduleName: ModuleName.OTHER, - }); - - useEffect(() => { - if (spanGroup && spanOp) { - openSamplesDrawer(); - } + requiredParams: ['spanGroup', 'spanOp'], }); return ( diff --git a/static/app/views/insights/queues/views/destinationSummaryPage.tsx b/static/app/views/insights/queues/views/destinationSummaryPage.tsx index 47d606966f6a6a..c6acbcbb1669c5 100644 --- a/static/app/views/insights/queues/views/destinationSummaryPage.tsx +++ b/static/app/views/insights/queues/views/destinationSummaryPage.tsx @@ -1,4 +1,4 @@ -import {Fragment, useEffect} from 'react'; +import {Fragment} from 'react'; import styled from '@emotion/styled'; import * as Layout from 'sentry/components/layouts/thirds'; @@ -43,15 +43,10 @@ function DestinationSummaryPage() { }); const errorRate = 1 - (data[0]?.['trace_status_rate(ok)'] ?? 0); - const {openSamplesDrawer} = useSamplesDrawer({ + useSamplesDrawer({ Component: , moduleName: ModuleName.QUEUE, - }); - - useEffect(() => { - if (query.transaction) { - openSamplesDrawer(); - } + requiredParams: ['transaction'], }); return ( From f6ea428515559885ae60fb59f48804273a5ceadc Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Tue, 7 Jan 2025 15:53:46 -0500 Subject: [PATCH 34/37] Omit more URL parameters on close --- static/app/components/globalDrawer/index.tsx | 12 +++++++----- .../views/insights/common/utils/useSamplesDrawer.tsx | 6 ++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/static/app/components/globalDrawer/index.tsx b/static/app/components/globalDrawer/index.tsx index 472b514c3a1423..0b1a3da53363db 100644 --- a/static/app/components/globalDrawer/index.tsx +++ b/static/app/components/globalDrawer/index.tsx @@ -94,10 +94,9 @@ export function GlobalDrawer({children}) { >(); // If no config is set, the global drawer is closed. const isDrawerOpen = !!currentDrawerConfig; - const openDrawer = useCallback( - (renderer, options) => overwriteDrawerConfig({renderer, options}), - [] - ); + const openDrawer = useCallback((renderer, options) => { + overwriteDrawerConfig({renderer, options}); + }, []); const closeDrawer = useCallback( () => overwriteDrawerConfig(undefined), [] @@ -112,7 +111,10 @@ export function GlobalDrawer({children}) { useLayoutEffect( () => { // Defaults to closing the drawer when the location changes - if (currentDrawerConfig?.options.shouldCloseOnLocationChange?.(location) ?? true) { + if ( + (currentDrawerConfig?.options.shouldCloseOnLocationChange?.(location) ?? true) && + isDrawerOpen + ) { // Call `closeDrawer` without invoking `onClose` callback, since those callbacks often update the URL closeDrawer(); } diff --git a/static/app/views/insights/common/utils/useSamplesDrawer.tsx b/static/app/views/insights/common/utils/useSamplesDrawer.tsx index 0f5f41c96a776b..e86b1cda437a3a 100644 --- a/static/app/views/insights/common/utils/useSamplesDrawer.tsx +++ b/static/app/views/insights/common/utils/useSamplesDrawer.tsx @@ -35,6 +35,12 @@ export function useSamplesDrawer({ spanGroup: undefined, spanOp: undefined, query: undefined, + responseCodeClass: undefined, + panel: undefined, + statusClass: undefined, + spanSearchQuery: undefined, + traceStatus: undefined, + retryCount: undefined, }, }); }, [navigate, location.query]); From a7980f6f7f588285b38fdf04734fd87e24f45cb9 Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Wed, 8 Jan 2025 11:26:58 -0500 Subject: [PATCH 35/37] Improve layout --- .../insights/common/components/sampleDrawerBody.tsx | 1 + .../app/views/insights/common/utils/useSamplesDrawer.tsx | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/static/app/views/insights/common/components/sampleDrawerBody.tsx b/static/app/views/insights/common/components/sampleDrawerBody.tsx index ad48a32c56978a..38bc7ba5f8f898 100644 --- a/static/app/views/insights/common/components/sampleDrawerBody.tsx +++ b/static/app/views/insights/common/components/sampleDrawerBody.tsx @@ -4,6 +4,7 @@ import {DrawerBody} from 'sentry/components/globalDrawer/components'; import {space} from 'sentry/styles/space'; export const SampleDrawerBody = styled(DrawerBody)` + flex-grow: 1; overflow: auto; overscroll-behavior: contain; /* Move the scrollbar to the left edge */ diff --git a/static/app/views/insights/common/utils/useSamplesDrawer.tsx b/static/app/views/insights/common/utils/useSamplesDrawer.tsx index e86b1cda437a3a..68c3f7346a0b91 100644 --- a/static/app/views/insights/common/utils/useSamplesDrawer.tsx +++ b/static/app/views/insights/common/utils/useSamplesDrawer.tsx @@ -1,4 +1,5 @@ import {useCallback, useEffect} from 'react'; +import styled from '@emotion/styled'; import type {Location} from 'history'; import useDrawer from 'sentry/components/globalDrawer'; @@ -62,7 +63,7 @@ export function useSamplesDrawer({ source: moduleName, }); - openDrawer(() => Component, { + openDrawer(() => {Component}, { ariaLabel: t('Samples'), onClose, transitionProps: {stiffness: 1000}, @@ -91,3 +92,9 @@ export function useSamplesDrawer({ } }, [shouldDrawerOpen, openSamplesDrawer, closeDrawer]); } + +const FullHeightWrapper = styled('div')` + height: 100%; + display: flex; + flex-direction: column; +`; From f1dbc694b09ba4283ca45d6bcff2872fe0b8f027 Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Fri, 10 Jan 2025 16:52:06 -0500 Subject: [PATCH 36/37] Unroll drawer change --- static/app/components/globalDrawer/index.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/static/app/components/globalDrawer/index.tsx b/static/app/components/globalDrawer/index.tsx index 0b1a3da53363db..472b514c3a1423 100644 --- a/static/app/components/globalDrawer/index.tsx +++ b/static/app/components/globalDrawer/index.tsx @@ -94,9 +94,10 @@ export function GlobalDrawer({children}) { >(); // If no config is set, the global drawer is closed. const isDrawerOpen = !!currentDrawerConfig; - const openDrawer = useCallback((renderer, options) => { - overwriteDrawerConfig({renderer, options}); - }, []); + const openDrawer = useCallback( + (renderer, options) => overwriteDrawerConfig({renderer, options}), + [] + ); const closeDrawer = useCallback( () => overwriteDrawerConfig(undefined), [] @@ -111,10 +112,7 @@ export function GlobalDrawer({children}) { useLayoutEffect( () => { // Defaults to closing the drawer when the location changes - if ( - (currentDrawerConfig?.options.shouldCloseOnLocationChange?.(location) ?? true) && - isDrawerOpen - ) { + if (currentDrawerConfig?.options.shouldCloseOnLocationChange?.(location) ?? true) { // Call `closeDrawer` without invoking `onClose` callback, since those callbacks often update the URL closeDrawer(); } From 024461868f5e6a2281fa41912b6b77f8e6962cc7 Mon Sep 17 00:00:00 2001 From: George Gritsouk <989898+gggritso@users.noreply.github.com> Date: Sun, 12 Jan 2025 17:52:40 -0500 Subject: [PATCH 37/37] Whoops wrong router --- static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx b/static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx index f234210d1bc271..186e9b46428371 100644 --- a/static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx +++ b/static/app/views/insights/mobile/ui/views/screenSummaryPage.tsx @@ -1,6 +1,5 @@ import {Fragment} from 'react'; import styled from '@emotion/styled'; -import {useRouter} from '@react-aria/utils'; import omit from 'lodash/omit'; import * as Layout from 'sentry/components/layouts/thirds'; @@ -9,6 +8,7 @@ import {space} from 'sentry/styles/space'; import {PageAlert, PageAlertProvider} from 'sentry/utils/performance/contexts/pageAlert'; import {useLocation} from 'sentry/utils/useLocation'; import useOrganization from 'sentry/utils/useOrganization'; +import useRouter from 'sentry/utils/useRouter'; import {HeaderContainer} from 'sentry/views/insights/common/components/headerContainer'; import {ModulePageFilterBar} from 'sentry/views/insights/common/components/modulePageFilterBar'; import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders';