Skip to content
4 changes: 4 additions & 0 deletions static/app/components/core/layout/container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ interface ContainerLayoutProps {

cursor?: Responsive<React.CSSProperties['cursor']>;

contain?: Responsive<React.CSSProperties['contain']>;

radius?: Responsive<Shorthand<RadiusSize, 4>>;

width?: Responsive<React.CSSProperties['width']>;
Expand Down Expand Up @@ -195,6 +197,7 @@ const omitContainerProps = new Set<keyof ContainerLayoutProps | 'as'>([
'borderRight',
'bottom',
'column',
'contain',
'cursor',
'display',
'flex',
Expand Down Expand Up @@ -275,6 +278,7 @@ export const Container = styled(
${p => rc('pointer-events', p.pointerEvents, p.theme)};

${p => rc('cursor', p.cursor, p.theme)};
${p => rc('contain', p.contain, p.theme)};

${p => rc('padding', p.padding, p.theme, getSpacing)};
${p => rc('padding-top', p.paddingTop, p.theme, getSpacing)};
Expand Down
212 changes: 113 additions & 99 deletions static/app/views/feedback/feedbackListPage.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type {ReactNode} from 'react';
import {Fragment, useEffect, useState} from 'react';
import {useTheme} from '@emotion/react';
import styled from '@emotion/styled';
Expand Down Expand Up @@ -40,6 +41,48 @@ const userFeedbackFeedbackOptions = {
},
};

function PageContent({
hideTop,
hasFeedbackContent,
content,
}: {
content: ReactNode;
hasFeedbackContent: boolean;
hideTop: boolean;
}) {
return (
<PageFiltersContainer>
<ErrorBoundary>
<Stack flex={1} align="stretch" gap="xl" background="primary" overflow="hidden">
<LayoutGrid hideTop={hideTop}>
{!hideTop && (
<Stack
flexGrow={1}
gap="md"
area="top"
direction={{xs: 'column', sm: 'row'}}
align={{xs: 'stretch', sm: 'start'}}
>
<FeedbackFilters />
<SearchContainer>
<FeedbackSearch />
</SearchContainer>
</Stack>
)}
{hasFeedbackContent ? (
content
) : (
<SetupContainer>
<FeedbackSetupPanel />
</SetupContainer>
)}
</LayoutGrid>
</Stack>
</ErrorBoundary>
</PageFiltersContainer>
);
}

export default function FeedbackListPage() {
const hasPageFrameFeature = useHasPageFrameFeature();
const organization = useOrganization();
Expand Down Expand Up @@ -144,112 +187,82 @@ export default function FeedbackListPage() {

// on medium and smaller screens, hide the search & filters when feedback item is in view
const hideTop = isMediumOrSmaller && showItemPreview;
const hasFeedbackContent = hasSetupOneFeedback || hasSlug;
const pageContent = isMediumOrSmaller ? smallerScreenView : largeScreenView;
const titleContent = (
<Fragment>
{t('User Feedback')}
<PageHeadingQuestionTooltip
title={t(
'The User Feedback Widget allows users to submit feedback quickly and easily any time they encounter something that isn’t working as expected.'
)}
docsUrl="https://docs.sentry.io/product/user-feedback/"
/>
</Fragment>
);
const createAlertAction = {
icon: <IconSiren />,
to: {
pathname: makeAlertsPathname({
path: '/new/issue/',
organization,
}),
query: {
alert_option: 'issues',
referrer: 'feedback-list-page',
detectorType: 'metric_issue',
...(feedbackProjectSlug ? {project: feedbackProjectSlug} : {}),
},
},
};

if (hasPageFrameFeature) {
return (
<SentryDocumentTitle title={t('User Feedback')} orgSlug={organization.slug}>
<Stack flex={1} contain="size">
<FeedbackQueryKeys organization={organization}>
<TopBar.Slot name="title">{titleContent}</TopBar.Slot>
<TopBar.Slot name="actions">
<LinkButton {...createAlertAction}>{t('Create Alert')}</LinkButton>
</TopBar.Slot>
<TopBar.Slot name="feedback">
<FeedbackButton size="sm" feedbackOptions={userFeedbackFeedbackOptions}>
{null}
</FeedbackButton>
</TopBar.Slot>
<PageContent
hideTop={hideTop}
hasFeedbackContent={hasFeedbackContent}
content={pageContent}
/>
</FeedbackQueryKeys>
</Stack>
</SentryDocumentTitle>
);
}

return (
<SentryDocumentTitle title={t('User Feedback')} orgSlug={organization.slug}>
<FullViewport>
<FeedbackQueryKeys organization={organization}>
<Layout.Header unified>
<Layout.HeaderContent unified>
<Layout.Title>
{t('User Feedback')}
<PageHeadingQuestionTooltip
title={t(
'The User Feedback Widget allows users to submit feedback quickly and easily any time they encounter something that isn’t working as expected.'
)}
docsUrl="https://docs.sentry.io/product/user-feedback/"
/>
</Layout.Title>
<Layout.Title>{titleContent}</Layout.Title>
</Layout.HeaderContent>
{hasPageFrameFeature ? (
<Fragment>
<TopBar.Slot name="actions">
<LinkButton
icon={<IconSiren />}
to={{
pathname: makeAlertsPathname({
path: '/new/issue/',
organization,
}),
query: {
alert_option: 'issues',
referrer: 'feedback-list-page',
detectorType: 'metric_issue',
...(feedbackProjectSlug ? {project: feedbackProjectSlug} : {}),
},
}}
>
{t('Create Alert')}
</LinkButton>
</TopBar.Slot>
<TopBar.Slot name="feedback">
<FeedbackButton size="sm" feedbackOptions={userFeedbackFeedbackOptions}>
{null}
</FeedbackButton>
</TopBar.Slot>
</Fragment>
) : (
<Layout.HeaderActions>
<Flex gap="lg">
<FeedbackButton
size="sm"
feedbackOptions={userFeedbackFeedbackOptions}
/>
<LinkButton
size="sm"
icon={<IconSiren />}
to={{
pathname: makeAlertsPathname({
path: '/new/issue/',
organization,
}),
query: {
alert_option: 'issues',
referrer: 'feedback-list-page',
detectorType: 'metric_issue',
...(feedbackProjectSlug ? {project: feedbackProjectSlug} : {}),
},
}}
>
{t('Create Alert')}
</LinkButton>
</Flex>
</Layout.HeaderActions>
)}
<Layout.HeaderActions>
<Flex gap="lg">
<FeedbackButton size="sm" feedbackOptions={userFeedbackFeedbackOptions} />
<LinkButton size="sm" {...createAlertAction}>
{t('Create Alert')}
</LinkButton>
</Flex>
</Layout.HeaderActions>
</Layout.Header>
<PageFiltersContainer>
<ErrorBoundary>
<Stack align="stretch" gap="xl" background="primary" overflow="hidden">
<LayoutGrid hideTop={hideTop}>
{!hideTop && (
<Stack
flexGrow={1}
gap="md"
area="top"
direction={{xs: 'column', sm: 'row'}}
align={{xs: 'stretch', sm: 'start'}}
>
<FeedbackFilters />
<SearchContainer>
<FeedbackSearch />
</SearchContainer>
</Stack>
)}
{hasSetupOneFeedback || hasSlug ? (
isMediumOrSmaller ? (
smallerScreenView
) : (
largeScreenView
)
) : (
<SetupContainer>
<FeedbackSetupPanel />
</SetupContainer>
)}
</LayoutGrid>
</Stack>
</ErrorBoundary>
</PageFiltersContainer>
<PageContent
hideTop={hideTop}
hasFeedbackContent={hasFeedbackContent}
content={pageContent}
/>
</FeedbackQueryKeys>
</FullViewport>
</SentryDocumentTitle>
Expand All @@ -258,7 +271,8 @@ export default function FeedbackListPage() {

const LayoutGrid = styled('div')<{hideTop?: boolean}>`
overflow: hidden;
flex-grow: 1;
flex: 1;
min-height: 0;

display: grid;
gap: ${p => p.theme.space.xl};
Expand All @@ -270,7 +284,7 @@ const LayoutGrid = styled('div')<{hideTop?: boolean}>`
padding: ${p => p.theme.space.xl} ${p => p.theme.space['3xl']};
}

grid-template-rows: max-content 1fr;
grid-template-rows: max-content minmax(0, 1fr);
grid-template-areas:
'top top'
'list details';
Expand Down
3 changes: 2 additions & 1 deletion static/app/views/replays/detail/layout/replayLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,14 @@ const FluidContainer = styled('section')`
gap: ${p => p.theme.space.md};
`;

const BodyGrid = styled('main')`
const BodyGrid = styled('div')`
background: ${p => p.theme.tokens.background.primary};

display: grid;
grid-template-rows: 1fr auto;
gap: ${p => p.theme.space.xl};
padding: ${p => p.theme.space.xl};
flex: 1;

/*
Grid items have default \`min-height: auto\` to contain all content.
Expand Down
63 changes: 47 additions & 16 deletions static/app/views/replays/details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,32 +93,63 @@ function ReplayDetailsContent() {

const hasPageFrame = useHasPageFrameFeature();

const content = (
<Fragment>
<Flex direction="column">
if (hasPageFrame) {
const pageFrameContent = (
<Fragment>
<TopBar.Slot name="title">
<ReplayDetailsPageBreadcrumbs readerResult={readerResult} />
</TopBar.Slot>
<ReplayDetailsHeaderActions readerResult={readerResult} />
<Flex
borderBottom={hasPageFrame ? undefined : 'secondary'}
justify="between"
align="center"
gap="md"
wrap="wrap"
padding={hasPageFrame ? '0' : 'sm lg'}
padding={{sm: 'md lg', md: 'md xl'}}
borderBottom="secondary"
>
{hasPageFrame ? (
<TopBar.Slot name="title">
<ReplayDetailsPageBreadcrumbs readerResult={readerResult} />
</TopBar.Slot>
<ReplayDetailsUserBadge readerResult={readerResult} />
<ReplayDetailsMetadata readerResult={readerResult} />
</Flex>
<Stack flex={1} minHeight="0" overflow="hidden" padding="lg xl">
<ReplayDetailsPage readerResult={readerResult} />
</Stack>
</Fragment>
);

return (
<SentryDocumentTitle title={title}>
<Stack flex={1} height="100%" minHeight="0" width="100%" overflow="hidden">
{replay ? (
<ReplayDetailsProviders
replay={replay}
projectSlug={readerResult.projectSlug}
>
{pageFrameContent}
</ReplayDetailsProviders>
) : (
<ReplayDetailsPageBreadcrumbs readerResult={readerResult} />
pageFrameContent
)}
<ReplayDetailsHeaderActions readerResult={readerResult} />
</Flex>
</Stack>
</SentryDocumentTitle>
);
}

const legacyContent = (
<Fragment>
<Flex direction="column">
<Flex
borderBottom="secondary"
justify="between"
align="center"
padding={hasPageFrame ? {sm: 'md lg', md: 'md xl'} : 'md lg'}
borderBottom="secondary"
gap="md"
wrap="wrap"
padding="sm lg"
>
<ReplayDetailsPageBreadcrumbs readerResult={readerResult} />
<ReplayDetailsHeaderActions readerResult={readerResult} />
</Flex>
<Flex justify="between" align="center" padding="md lg" borderBottom="secondary">
<ReplayDetailsUserBadge readerResult={readerResult} />
<ReplayDetailsMetadata readerResult={readerResult} />
</Flex>
Expand All @@ -136,10 +167,10 @@ function ReplayDetailsContent() {
replay={replay}
projectSlug={readerResult.projectSlug}
>
{content}
{legacyContent}
</ReplayDetailsProviders>
) : (
content
legacyContent
)}
</FullViewport>
</Stack>
Expand Down
Loading
Loading