Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 34 additions & 16 deletions static/app/views/dashboards/detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1179,27 +1179,45 @@ class DashboardDetail extends Component<Props, State> {
<MetricsResultsMetaProvider>
<NoProjectMessage organization={organization}>
{this.isEmbedded ? null : (
<Layout.Header>
<Layout.HeaderContent>
<Breadcrumbs
crumbs={[
{
label: t('Dashboards'),
to: `/organizations/${organization.slug}/dashboards/`,
},
{
label: this.getBreadcrumbLabel(),
},
]}
/>
<Layout.Title>
<Layout.Header unified={this.props.hasPageFrameFeature}>
{this.props.hasPageFrameFeature ? (
<TopBar.Slot name="title">
<Breadcrumbs
crumbs={[
{
label: t('Dashboards'),
to: `/organizations/${organization.slug}/dashboards/`,
},
]}
/>
<DashboardTitle
Comment thread
natemoo-re marked this conversation as resolved.
dashboard={modifiedDashboard ?? dashboard}
onUpdate={this.setModifiedDashboard}
isEditingDashboard={this.isEditingDashboard}
/>
</Layout.Title>
</Layout.HeaderContent>
</TopBar.Slot>
) : (
<Layout.HeaderContent>
<Breadcrumbs
crumbs={[
{
label: t('Dashboards'),
to: `/organizations/${organization.slug}/dashboards/`,
},
{
label: this.getBreadcrumbLabel(),
},
]}
/>
<Layout.Title>
<DashboardTitle
dashboard={modifiedDashboard ?? dashboard}
onUpdate={this.setModifiedDashboard}
isEditingDashboard={this.isEditingDashboard}
/>
</Layout.Title>
</Layout.HeaderContent>
)}
Comment thread
cursor[bot] marked this conversation as resolved.
{this.props.hasPageFrameFeature ? (
<TopBar.Slot name="actions">
<Controls
Expand Down
15 changes: 13 additions & 2 deletions static/app/views/detectors/components/details/common/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
makeMonitorTypePathname,
} from 'sentry/views/detectors/pathnames';
import {getDetectorTypeLabel} from 'sentry/views/detectors/utils/detectorTypeConfig';
import {TopBar} from 'sentry/views/navigation/topBar';
import {useHasPageFrameFeature} from 'sentry/views/navigation/useHasPageFrameFeature';

type DetectorDetailsHeaderProps = {
detector: Detector;
Expand Down Expand Up @@ -46,10 +48,19 @@ export function DetectorDetailsDefaultHeaderContent({
detector: Detector;
project: Project;
}) {
const hasPageFrameFeature = useHasPageFrameFeature();
return (
<DetailLayout.HeaderContent>
<DetectorDetailsBreadcrumbs detector={detector} />
<DetailLayout.Title title={detector.name} project={project} />
{hasPageFrameFeature ? (
<TopBar.Slot name="title">
<DetectorDetailsBreadcrumbs detector={detector} />
</TopBar.Slot>
) : (
<DetectorDetailsBreadcrumbs detector={detector} />
)}
{!hasPageFrameFeature && (
<DetailLayout.Title title={detector.name} project={project} />
)}
</DetailLayout.HeaderContent>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {DetectorNameField} from 'sentry/views/detectors/components/forms/common/
import {NewDetectorFooter} from 'sentry/views/detectors/components/forms/common/footer';
import {MonitorFeedbackButton} from 'sentry/views/detectors/components/monitorFeedbackButton';
import {useCreateDetectorFormSubmit} from 'sentry/views/detectors/hooks/useCreateDetectorFormSubmit';
import {TopBar} from 'sentry/views/navigation/topBar';
import {useHasPageFrameFeature} from 'sentry/views/navigation/useHasPageFrameFeature';

type NewDetectorLayoutProps<TFormData, TUpdatePayload> = {
children: React.ReactNode;
Expand Down Expand Up @@ -47,6 +49,7 @@ export function NewDetectorLayout<
const theme = useTheme();
const maxWidth = theme.breakpoints.xl;
const {projects} = useProjects();
const hasPageFrame = useHasPageFrameFeature();

const initialProjectId = useMemo(() => {
const queryProjectId = location.query.project as string | undefined;
Expand Down Expand Up @@ -97,7 +100,13 @@ export function NewDetectorLayout<
<EditLayout formProps={formProps}>
<EditLayout.Header maxWidth={maxWidth}>
<EditLayout.HeaderContent>
<NewDetectorBreadcrumbs detectorType={detectorType} />
{hasPageFrame ? (
<TopBar.Slot name="title">
<NewDetectorBreadcrumbs detectorType={detectorType} />
</TopBar.Slot>
) : (
<NewDetectorBreadcrumbs detectorType={detectorType} />
)}
</EditLayout.HeaderContent>

<div>
Expand Down
13 changes: 11 additions & 2 deletions static/app/views/detectors/new.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
} from 'sentry/views/detectors/components/detectorTypeForm';
import {MonitorFeedbackButton} from 'sentry/views/detectors/components/monitorFeedbackButton';
import {makeMonitorBasePathname} from 'sentry/views/detectors/pathnames';
import {TopBar} from 'sentry/views/navigation/topBar';
import {useHasPageFrameFeature} from 'sentry/views/navigation/useHasPageFrameFeature';

function NewDetectorBreadcrumbs() {
const organization = useOrganization();
Expand All @@ -42,6 +44,7 @@ export default function DetectorNew() {
useWorkflowEngineFeatureGate({redirect: true});
const theme = useTheme();
const maxWidth = theme.breakpoints.xl;
const hasPageFrame = useHasPageFrameFeature();
const [detectorType] = useDetectorTypeQueryState();
const [projectId] = useQueryState('project', parseAsString);

Expand All @@ -65,8 +68,14 @@ export default function DetectorNew() {
<SentryDocumentTitle title={t('New Monitor')} />
<EditLayout.Header maxWidth={maxWidth}>
<EditLayout.HeaderContent>
<NewDetectorBreadcrumbs />
<EditLayout.Title title={t('Select monitor type')} />
{hasPageFrame ? (
<TopBar.Slot name="title">
<NewDetectorBreadcrumbs />
</TopBar.Slot>
) : (
<NewDetectorBreadcrumbs />
)}
{!hasPageFrame && <EditLayout.Title title={t('Select monitor type')} />}
<Text as="p" size="md" variant="muted">
{tct(
'Monitors detect problems in your application and send alerts when they occur. [docsLink:Read the Docs].',
Expand Down
4 changes: 3 additions & 1 deletion static/app/views/explore/components/breadcrumb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import {makeTracesPathname} from 'sentry/views/traces/pathnames';

export function ExploreBreadcrumb({
traceItemDataset,
savedQueryName,
}: {
traceItemDataset: TraceItemDataset;
savedQueryName?: string;
}) {
const organization = useOrganization();
const crumbs: Crumb[] = [];
Expand Down Expand Up @@ -40,7 +42,7 @@ export function ExploreBreadcrumb({
});
}
crumbs.push({
label: t('Saved Query'),
label: savedQueryName ?? t('Saved Query'),
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.

Nullish coalescing allows empty string breadcrumb label

Low Severity

The ?? (nullish coalescing) operator only guards against null/undefined, not empty strings. If savedQueryName is "", the breadcrumb label becomes an empty string instead of falling back to t('Saved Query'). This can happen because the calling sites pass savedQuery?.name which could be an empty string when a saved query exists but has no name. The || operator would correctly handle this case by also falling back on falsy values like "".

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6b41450. Configure here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Edge case

});

return <Breadcrumbs crumbs={crumbs} />;
Expand Down
5 changes: 4 additions & 1 deletion static/app/views/explore/logs/content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,10 @@ function LogsHeader() {
/>
) : null}
{title && defined(pageId) ? (
<ExploreBreadcrumb traceItemDataset={TraceItemDataset.LOGS} />
<ExploreBreadcrumb
traceItemDataset={TraceItemDataset.LOGS}
savedQueryName={savedQuery?.name}
/>
) : null}

<Layout.Title>{title ? title : t('Logs')}</Layout.Title>
Expand Down
5 changes: 4 additions & 1 deletion static/app/views/explore/metrics/content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,10 @@ function MetricsHeader() {
/>
) : null}
{title && defined(pageId) ? (
<ExploreBreadcrumb traceItemDataset={TraceItemDataset.TRACEMETRICS} />
<ExploreBreadcrumb
traceItemDataset={TraceItemDataset.TRACEMETRICS}
savedQueryName={savedQuery?.name}
/>
) : null}
<Layout.Title>
{title ? title : METRICS_TITLE}
Expand Down
60 changes: 47 additions & 13 deletions static/app/views/explore/spans/content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,19 +167,53 @@ function SpansTabHeader() {
orgSlug={organization?.slug}
/>
) : null}
{title && defined(id) ? (
<ExploreBreadcrumb traceItemDataset={TraceItemDataset.SPANS} />
) : null}
<Layout.Title>
{title ? title : t('Traces')}
<PageHeadingQuestionTooltip
docsUrl="https://github.com/getsentry/sentry/discussions/81239"
title={t(
'Find problematic spans/traces or compute real-time metrics via aggregation.'
)}
linkLabel={t('Read the Discussion')}
/>
</Layout.Title>
{hasPageFrameFeature ? (
title && defined(id) ? (
<TopBar.Slot name="title">
<ExploreBreadcrumb
traceItemDataset={TraceItemDataset.SPANS}
savedQueryName={savedQuery?.name}
/>
<PageHeadingQuestionTooltip
docsUrl="https://github.com/getsentry/sentry/discussions/81239"
title={t(
'Find problematic spans/traces or compute real-time metrics via aggregation.'
)}
linkLabel={t('Read the Discussion')}
/>
</TopBar.Slot>
) : (
<TopBar.Slot name="title">
{title ? title : t('Traces')}
<PageHeadingQuestionTooltip
docsUrl="https://github.com/getsentry/sentry/discussions/81239"
title={t(
'Find problematic spans/traces or compute real-time metrics via aggregation.'
)}
linkLabel={t('Read the Discussion')}
/>
</TopBar.Slot>
)
Comment thread
sentry[bot] marked this conversation as resolved.
) : (
<Fragment>
{title && defined(id) ? (
<ExploreBreadcrumb
traceItemDataset={TraceItemDataset.SPANS}
savedQueryName={savedQuery?.name}
/>
) : null}
<Layout.Title>
{title ? title : t('Traces')}
<PageHeadingQuestionTooltip
docsUrl="https://github.com/getsentry/sentry/discussions/81239"
title={t(
'Find problematic spans/traces or compute real-time metrics via aggregation.'
)}
linkLabel={t('Read the Discussion')}
/>
</Layout.Title>
</Fragment>
)}
</Layout.HeaderContent>
{hasPageFrameFeature ? (
<Fragment>
Expand Down
45 changes: 32 additions & 13 deletions static/app/views/issueDetails/streamline/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,20 +118,39 @@ export function StreamlinedGroupHeader({event, group, project}: GroupHeaderProps
<Header>
<Flex justify="between">
<Flex align="center" gap="md">
<StyledBreadcrumbs
crumbs={[
{
label: 'Issues',
to: {
pathname: `/organizations/${organization.slug}/issues/`,
query,
{hasPageFrameFeature ? (
<TopBar.Slot name="title">
<StyledBreadcrumbs
crumbs={[
{
label: 'Issues',
to: {
pathname: `/organizations/${organization.slug}/issues/`,
query,
},
},
{
label: <IssueIdBreadcrumb project={project} group={group} />,
},
]}
/>
</TopBar.Slot>
) : (
<StyledBreadcrumbs
crumbs={[
{
label: 'Issues',
to: {
pathname: `/organizations/${organization.slug}/issues/`,
query,
},
},
{
label: <IssueIdBreadcrumb project={project} group={group} />,
},
},
{
label: <IssueIdBreadcrumb project={project} group={group} />,
},
]}
/>
]}
/>
)}
{hasErrorUpsampling && (
<Tooltip
title={t(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,31 @@ export function TraceMetaDataHeader(props: TraceMetadataHeaderProps) {
<TraceHeaderComponents.HeaderLayout>
<TraceHeaderComponents.HeaderContent>
<TraceHeaderComponents.HeaderRow>
<Breadcrumbs
crumbs={getTraceViewBreadcrumbs({
organization: props.organization,
location,
moduleURLBuilder,
traceSlug: props.traceSlug,
project,
view,
})}
/>
{hasPageFrameFeature ? (
<TopBar.Slot name="title">
<Breadcrumbs
crumbs={getTraceViewBreadcrumbs({
organization: props.organization,
location,
moduleURLBuilder,
traceSlug: props.traceSlug,
project,
view,
})}
/>
</TopBar.Slot>
) : (
<Breadcrumbs
crumbs={getTraceViewBreadcrumbs({
organization: props.organization,
location,
moduleURLBuilder,
traceSlug: props.traceSlug,
project,
view,
})}
/>
)}
<Grid flow="column" align="center" gap="md">
{hasPageFrameFeature ? (
<TopBar.Slot name="feedback">
Expand Down
13 changes: 10 additions & 3 deletions static/app/views/replays/details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {useLocation} from 'sentry/utils/useLocation';
import {useOrganization} from 'sentry/utils/useOrganization';
import {useParams} from 'sentry/utils/useParams';
import {useUser} from 'sentry/utils/useUser';
import {TopBar} from 'sentry/views/navigation/topBar';
import {useHasPageFrameFeature} from 'sentry/views/navigation/useHasPageFrameFeature';
import {ReplayDetailsProviders} from 'sentry/views/replays/detail/body/replayDetailsProviders';
import {ReplayDetailsHeaderActions} from 'sentry/views/replays/detail/header/replayDetailsHeaderActions';
Expand Down Expand Up @@ -96,14 +97,20 @@ function ReplayDetailsContent() {
<Fragment>
<Flex direction="column">
<Flex
borderBottom="secondary"
borderBottom={hasPageFrame ? undefined : 'secondary'}
justify="between"
align="center"
gap="md"
wrap="wrap"
padding={hasPageFrame ? {sm: 'sm lg', md: 'md xl'} : 'sm lg'}
padding={hasPageFrame ? '0' : 'sm lg'}
>
<ReplayDetailsPageBreadcrumbs readerResult={readerResult} />
{hasPageFrame ? (
<TopBar.Slot name="title">
<ReplayDetailsPageBreadcrumbs readerResult={readerResult} />
</TopBar.Slot>
) : (
<ReplayDetailsPageBreadcrumbs readerResult={readerResult} />
)}
<ReplayDetailsHeaderActions readerResult={readerResult} />
</Flex>
<Flex
Expand Down
Loading
Loading