Skip to content
Merged
6 changes: 3 additions & 3 deletions static/app/views/insights/pages/conversations/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import {Fragment} from 'react';
import {Outlet, useMatches} from 'react-router-dom';

import * as Layout from 'sentry/components/layouts/thirds';
import {ConversationsPageHeader} from 'sentry/views/insights/pages/conversations/conversationsPageHeader';
import {ModuleName} from 'sentry/views/insights/types';

function ConversationsLayout() {
const handle = useMatches().at(-1)?.handle as {module?: ModuleName} | undefined;

return (
<Fragment>
<Layout.Page>
{handle && 'module' in handle ? (
<ConversationsPageHeader module={handle.module} />
) : null}
<Outlet />
</Fragment>
</Layout.Page>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Layout wrapper at wrong level causes nested main elements

Medium Severity

Layout.Page is added to ConversationsLayout, which wraps all child routes via Outlet — including transactionSummaryRoute and traceView, both of which render their own Layout.Page. This creates nested <main> elements (semantically invalid HTML) and breaks the ~ footer { display: none; } CSS sibling selector on traceView's inner LayoutPageWithHiddenFooter, since the footer is now a sibling of the outer <main> only. The PR description indicates the fix belongs in overview.tsx, not layout.tsx.

Fix in Cursor Fix in Web

Copy link
Copy Markdown
Member

@priscilawebdev priscilawebdev Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a bug. The conversations page renders a table and drawer. transactionSummaryRoute and traceView are included as children following the same pattern as all other insight pages (frontend, backend, mobile, etc.). No visual or functional issue observed.

);
}

Expand Down
47 changes: 19 additions & 28 deletions static/app/views/profiling/continuousProfileFlamegraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import * as qs from 'query-string';

import {Stack} from '@sentry/scraps/layout';

import * as Layout from 'sentry/components/layouts/thirds';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {ContinuousFlamegraph} from 'sentry/components/profiling/flamegraph/continuousFlamegraph';
import {SentryDocumentTitle} from 'sentry/components/sentryDocumentTitle';
Expand Down Expand Up @@ -104,27 +103,25 @@ export default function ContinuousProfileFlamegraphWrapper() {
title={t('Profiling \u2014 Flamechart')}
orgSlug={organization.slug}
>
<LayoutPageWithHiddenFooter>
<FlamegraphStateProvider initialState={initialFlamegraphPreferencesState}>
<ProfileGroupTypeProvider
input={profiles.type === 'resolved' ? profiles.data : null}
traceID={params.eventId!}
>
<FlamegraphThemeProvider>
<FlamegraphStateQueryParamSync />
<FlamegraphStateLocalStorageSync />
<FlamegraphContainer>
{profiles.type === 'loading' ? (
<Stack justify="center" width="100%" height="100%" position="absolute">
<LoadingIndicator />
</Stack>
) : null}
<ContinuousProfileFlamegraph />
</FlamegraphContainer>
</FlamegraphThemeProvider>
</ProfileGroupTypeProvider>
</FlamegraphStateProvider>
</LayoutPageWithHiddenFooter>
<FlamegraphStateProvider initialState={initialFlamegraphPreferencesState}>
<ProfileGroupTypeProvider
input={profiles.type === 'resolved' ? profiles.data : null}
traceID={params.eventId!}
>
<FlamegraphThemeProvider>
<FlamegraphStateQueryParamSync />
<FlamegraphStateLocalStorageSync />
<FlamegraphContainer>
{profiles.type === 'loading' ? (
<Stack justify="center" width="100%" height="100%" position="absolute">
<LoadingIndicator />
</Stack>
) : null}
<ContinuousProfileFlamegraph />
</FlamegraphContainer>
</FlamegraphThemeProvider>
</ProfileGroupTypeProvider>
</FlamegraphStateProvider>
</SentryDocumentTitle>
);
}
Expand Down Expand Up @@ -159,9 +156,3 @@ const FlamegraphContainer = styled('div')`
flex-direction: column;
flex: 1 1 100%;
`;

const LayoutPageWithHiddenFooter = styled(Layout.Page)`
~ footer {
display: none;
}
`;
15 changes: 9 additions & 6 deletions static/app/views/profiling/continuousProfileProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {decodeScalar} from 'sentry/utils/queryString';
import {useLocation} from 'sentry/utils/useLocation';
import {useOrganization} from 'sentry/utils/useOrganization';
import {useParams} from 'sentry/utils/useParams';
import {LayoutPageWithHiddenFooter} from 'sentry/views/profiling/layoutPageWithHiddenFooter';

import {ContinuousProfileProvider, ProfileTransactionContext} from './profilesProvider';

Expand Down Expand Up @@ -65,12 +66,14 @@ export default function ProfileAndTransactionProvider(): React.ReactElement {
setProfile={setProfile}
>
<ProfileTransactionContext value={profileTransaction}>
<ContinuousProfileHeader
transaction={
profileTransaction.type === 'resolved' ? profileTransaction.data : null
}
/>
<Outlet />
<LayoutPageWithHiddenFooter>
<ContinuousProfileHeader
transaction={
profileTransaction.type === 'resolved' ? profileTransaction.data : null
}
/>
<Outlet />
</LayoutPageWithHiddenFooter>
</ProfileTransactionContext>
</ContinuousProfileProvider>
);
Expand Down
31 changes: 15 additions & 16 deletions static/app/views/profiling/differentialFlamegraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {FlamegraphRenderer2D} from 'sentry/utils/profiling/renderers/flamegraphR
import {FlamegraphRendererWebGL} from 'sentry/utils/profiling/renderers/flamegraphRendererWebGL';
import {Rect} from 'sentry/utils/profiling/speedscope';
import {useLocation} from 'sentry/utils/useLocation';
import {LayoutPageWithHiddenFooter} from 'sentry/views/profiling/layoutPageWithHiddenFooter';
import {LOADING_PROFILE_GROUP} from 'sentry/views/profiling/profileGroupProvider';

const PROFILE_TYPE = 'differential aggregate flamegraph' as const;
Expand Down Expand Up @@ -348,26 +349,24 @@ const DifferentialFlamegraphContainer = styled('div')`
display: flex;
flex-direction: column;
flex: 1;

~ footer {
display: none;
}
`;

function DifferentialFlamegraphWithProviders() {
return (
<FlamegraphThemeProvider>
<FlamegraphStateProvider
initialState={{
preferences: {
sorting: 'alphabetical',
view: 'top down',
},
}}
>
<DifferentialFlamegraphView />
</FlamegraphStateProvider>
</FlamegraphThemeProvider>
<LayoutPageWithHiddenFooter>
<FlamegraphThemeProvider>
<FlamegraphStateProvider
initialState={{
preferences: {
sorting: 'alphabetical',
view: 'top down',
},
}}
>
<DifferentialFlamegraphView />
</FlamegraphStateProvider>
</FlamegraphThemeProvider>
</LayoutPageWithHiddenFooter>
);
}

Expand Down
12 changes: 12 additions & 0 deletions static/app/views/profiling/layoutPageWithHiddenFooter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import styled from '@emotion/styled';

import * as Layout from 'sentry/components/layouts/thirds';

// The footer component is a sibling of this div.
// Remove it so the flamegraph can take up the
// entire screen.
export const LayoutPageWithHiddenFooter = styled(Layout.Page)`
~ footer {
display: none;
}
`;
47 changes: 19 additions & 28 deletions static/app/views/profiling/profileFlamechart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import * as qs from 'query-string';

import {Stack} from '@sentry/scraps/layout';

import * as Layout from 'sentry/components/layouts/thirds';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {Flamegraph} from 'sentry/components/profiling/flamegraph/flamegraph';
import {SentryDocumentTitle} from 'sentry/components/sentryDocumentTitle';
Expand Down Expand Up @@ -105,27 +104,25 @@ export default function ProfileFlamegraphWrapper() {
title={t('Profiling \u2014 Flamechart')}
orgSlug={organization.slug}
>
<LayoutPageWithHiddenFooter>
<FlamegraphStateProvider initialState={initialFlamegraphPreferencesState}>
<ProfileGroupTypeProvider
input={profiles.type === 'resolved' ? profiles.data : null}
traceID={params.eventId!}
>
<FlamegraphThemeProvider>
<FlamegraphStateQueryParamSync />
<FlamegraphStateLocalStorageSync />
<FlamegraphContainer>
{profiles.type === 'loading' || profiledTransaction.type === 'loading' ? (
<Stack justify="center" width="100%" height="100%" position="absolute">
<LoadingIndicator />
</Stack>
) : null}
<ProfileFlamegraph />
</FlamegraphContainer>
</FlamegraphThemeProvider>
</ProfileGroupTypeProvider>
</FlamegraphStateProvider>
</LayoutPageWithHiddenFooter>
<FlamegraphStateProvider initialState={initialFlamegraphPreferencesState}>
<ProfileGroupTypeProvider
input={profiles.type === 'resolved' ? profiles.data : null}
traceID={params.eventId!}
>
<FlamegraphThemeProvider>
<FlamegraphStateQueryParamSync />
<FlamegraphStateLocalStorageSync />
<FlamegraphContainer>
{profiles.type === 'loading' || profiledTransaction.type === 'loading' ? (
<Stack justify="center" width="100%" height="100%" position="absolute">
<LoadingIndicator />
</Stack>
) : null}
<ProfileFlamegraph />
</FlamegraphContainer>
</FlamegraphThemeProvider>
</ProfileGroupTypeProvider>
</FlamegraphStateProvider>
</SentryDocumentTitle>
);
}
Expand Down Expand Up @@ -160,9 +157,3 @@ const FlamegraphContainer = styled('div')`
flex-direction: column;
flex: 1 1 100%;
`;

const LayoutPageWithHiddenFooter = styled(Layout.Page)`
~ footer {
display: none;
}
`;
22 changes: 8 additions & 14 deletions static/app/views/profiling/profileSummary/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import {
useFlamegraph,
} from 'sentry/views/profiling/flamegraphProvider';
import {ProfilesSummaryChart} from 'sentry/views/profiling/landing/profilesSummaryChart';
import {LayoutPageWithHiddenFooter} from 'sentry/views/profiling/layoutPageWithHiddenFooter';
import {ProfileGroupProvider} from 'sentry/views/profiling/profileGroupProvider';
import {ProfilesTable} from 'sentry/views/profiling/profileSummary/profilesTable';

Expand Down Expand Up @@ -636,15 +637,6 @@ const ProfileSummaryContainer = styled('div')`
display: flex;
flex-direction: column;
flex: 1 1 100%;

/*
* The footer component is a sibling of this div.
* Remove it so the flamegraph can take up the
* entire screen.
*/
~ footer {
display: none;
}
`;

const PROFILE_DIGEST_FIELDS = [
Expand Down Expand Up @@ -781,10 +773,12 @@ const ProfileDigestLabel = styled('span')`

export default function ProfileSummaryPageToggle() {
return (
<ProfileSummaryContainer data-test-id="profile-summary-redesign">
<ErrorBoundary>
<ProfileSummaryPage />
</ErrorBoundary>
</ProfileSummaryContainer>
<LayoutPageWithHiddenFooter>
<ProfileSummaryContainer data-test-id="profile-summary-redesign">
<ErrorBoundary>
<ProfileSummaryPage />
</ErrorBoundary>
</ProfileSummaryContainer>
</LayoutPageWithHiddenFooter>
);
}
19 changes: 11 additions & 8 deletions static/app/views/profiling/transactionProfileProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {isSchema, isSentrySampledProfile} from 'sentry/utils/profiling/guards/pr
import {useSentryEvent} from 'sentry/utils/profiling/hooks/useSentryEvent';
import {useOrganization} from 'sentry/utils/useOrganization';
import {useParams} from 'sentry/utils/useParams';
import {LayoutPageWithHiddenFooter} from 'sentry/views/profiling/layoutPageWithHiddenFooter';

import {ProfileTransactionContext, TransactionProfileProvider} from './profilesProvider';

Expand Down Expand Up @@ -46,14 +47,16 @@ export default function ProfileAndTransactionProvider(): React.ReactElement {
setProfile={setProfile}
>
<ProfileTransactionContext value={profileTransaction}>
<ProfileHeader
eventId={params.eventId!}
projectId={projectSlug}
transaction={
profileTransaction.type === 'resolved' ? profileTransaction.data : null
}
/>
<Outlet />
<LayoutPageWithHiddenFooter>
<ProfileHeader
eventId={params.eventId!}
projectId={projectSlug}
transaction={
profileTransaction.type === 'resolved' ? profileTransaction.data : null
}
/>
<Outlet />
</LayoutPageWithHiddenFooter>
</ProfileTransactionContext>
</TransactionProfileProvider>
);
Expand Down
17 changes: 10 additions & 7 deletions static/app/views/projectInstall/newProject.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import styled from '@emotion/styled';

import * as Layout from 'sentry/components/layouts/thirds';
import {SentryDocumentTitle} from 'sentry/components/sentryDocumentTitle';

import {CreateProject} from './createProject';

function NewProject() {
return (
<SentryDocumentTitle>
<Container>
<div className="container">
<Content>
<CreateProject />
</Content>
</div>
</Container>
<Layout.Page>
<Container>
<div className="container">
<Content>
<CreateProject />
</Content>
</div>
</Container>
</Layout.Page>
</SentryDocumentTitle>
);
}
Expand Down
Loading