Skip to content

Commit

Permalink
✨ implement issue details tour
Browse files Browse the repository at this point in the history
  • Loading branch information
leeandher committed Feb 27, 2025
1 parent 4c22522 commit 99fb3ec
Show file tree
Hide file tree
Showing 5 changed files with 311 additions and 225 deletions.
109 changes: 57 additions & 52 deletions static/app/views/issueDetails/streamline/eventDetailsHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Fragment, useEffect} from 'react';
import {useEffect} from 'react';
import {css, useTheme} from '@emotion/react';
import styled from '@emotion/styled';

Expand All @@ -7,6 +7,10 @@ import {Flex} from 'sentry/components/container/flex';
import ErrorBoundary from 'sentry/components/errorBoundary';
import {DatePageFilter} from 'sentry/components/organizations/datePageFilter';
import {EnvironmentPageFilter} from 'sentry/components/organizations/environmentPageFilter';
import {
IssueDetailsTour,
IssueDetailsTourElement,
} from 'sentry/components/tours/issueDetails';
import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import type {Event} from 'sentry/types/event';
Expand Down Expand Up @@ -67,53 +71,53 @@ export function EventDetailsHeader({group, event, project}: EventDetailsHeaderPr
issueTypeConfig.customCopy.eventUnits.toLocaleLowerCase()
);

const hasHeader =
issueTypeConfig.header.filterBar.enabled ||
issueTypeConfig.header.graph.enabled ||
issueTypeConfig.header.occurrenceSummary.enabled;

if (!hasHeader) {
return null;
}

return (
<PageErrorBoundary mini message={t('There was an error loading the event filters')}>
<FilterContainer
<DetailsContainer
role="group"
aria-description={t('Event filtering controls')}
hasFilterBar={issueTypeConfig.header.filterBar.enabled}
>
{issueTypeConfig.header.filterBar.enabled && (
<Fragment>
<EnvironmentSelector group={group} event={event} project={project} />
<DateFilter
triggerProps={{
borderless: true,
style: {
borderRadius: 0,
},
}}
/>
<Flex style={{gridArea: 'search'}}>
<SearchFilter
group={group}
handleSearch={query => {
navigate(
{...location, query: {...location.query, query}},
{replace: true}
);
}}
environments={environments}
query={searchQuery}
queryBuilderProps={{
disallowFreeText: true,
placeholder: searchText,
label: searchText,
<IssueDetailsTourElement
id={IssueDetailsTour.ISSUE_DETAILS_FILTERS}
title={t('Narrow your focus')}
description={t(
'Filtering events to a specific user, tag value, environment, or timeframe can speed up debugging and identifying the root cause.'
)}
position="bottom-start"
>
<FilterContainer>
<EnvironmentSelector group={group} event={event} project={project} />
<DateFilter
triggerProps={{
borderless: true,
style: {
borderRadius: 0,
},
}}
/>
<ToggleSidebar />
</Flex>
</Fragment>
<Flex>
<SearchFilter
group={group}
handleSearch={query => {
navigate(
{...location, query: {...location.query, query}},
{replace: true}
);
}}
environments={environments}
query={searchQuery}
queryBuilderProps={{
disallowFreeText: true,
placeholder: searchText,
label: searchText,
}}
/>
<ToggleSidebar />
</Flex>
</FilterContainer>
</IssueDetailsTourElement>
)}
{issueTypeConfig.header.graph.enabled && (
<GraphSection>
Expand Down Expand Up @@ -141,7 +145,7 @@ export function EventDetailsHeader({group, event, project}: EventDetailsHeaderPr
{issueTypeConfig.header.occurrenceSummary.enabled && (
<OccurrenceSummarySection group={group} event={event} />
)}
</FilterContainer>
</DetailsContainer>
</PageErrorBoundary>
);
}
Expand All @@ -153,7 +157,7 @@ function EnvironmentSelector({group, event, project}: EventDetailsHeaderProps) {
const eventEnvironment = event?.tags?.find(tag => tag.key === 'environment')?.value;

const environmentCss = css`
grid-area: env;
display: block;
&:before {
right: 0;
top: ${space(1)};
Expand Down Expand Up @@ -187,29 +191,32 @@ function EnvironmentSelector({group, event, project}: EventDetailsHeaderProps) {
);
}

const FilterContainer = styled('div')<{
const DetailsContainer = styled('div')<{
hasFilterBar: boolean;
}>`
padding-left: 24px;
display: grid;
grid-template-columns: auto auto minmax(100px, 1fr) auto;
grid-template-rows: ${p => (p.hasFilterBar ? 'minmax(38px, auto) auto auto' : 'auto')};
grid-template-areas:
'env date search toggle'
'graph graph graph graph'
'timeline timeline timeline timeline';
display: flex;
flex-direction: column;
border: 0px solid ${p => p.theme.translucentBorder};
border-width: 0 1px 1px 0;
`;

const FilterContainer = styled('div')`
display: grid;
grid-template-columns: auto auto minmax(100px, 1fr) auto;
grid-template-rows: minmax(38px, auto);
width: 100%;
`;

const SearchFilter = styled(EventSearch)`
display: block;
border-color: transparent;
border-radius: 0;
box-shadow: none;
`;

const DateFilter = styled(DatePageFilter)`
grid-area: date;
display: block;
&:before {
right: 0;
top: ${space(1)};
Expand All @@ -222,7 +229,6 @@ const DateFilter = styled(DatePageFilter)`
`;

const GraphSection = styled('div')`
grid-area: graph;
display: flex;
&:not(:first-child) {
border-top: 1px solid ${p => p.theme.translucentBorder};
Expand All @@ -231,7 +237,6 @@ const GraphSection = styled('div')`

const OccurrenceSummarySection = styled(OccurrenceSummary)`
white-space: unset;
grid-area: timeline;
padding: ${space(1)};
padding-left: 0;
&:not(:first-child) {
Expand Down
171 changes: 92 additions & 79 deletions static/app/views/issueDetails/streamline/eventNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import ButtonBar from 'sentry/components/buttonBar';
import Count from 'sentry/components/count';
import DropdownButton from 'sentry/components/dropdownButton';
import {DropdownMenu} from 'sentry/components/dropdownMenu';
import {
IssueDetailsTour,
IssueDetailsTourElement,
} from 'sentry/components/tours/issueDetails';
import {IconTelescope} from 'sentry/icons';
import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';
Expand Down Expand Up @@ -187,91 +191,100 @@ export function IssueEventNavigation({event, group}: IssueEventNavigationProps)
/>
<LargeInThisIssueText aria-hidden>{t('in this issue')}</LargeInThisIssueText>
</LargeDropdownButtonWrapper>
<NavigationWrapper>
{currentTab === Tab.DETAILS && (
<Fragment>
<IssueDetailsEventNavigation event={event} group={group} />
{issueTypeConfig.pages.events.enabled && (
<LinkButton
to={{
pathname: `${baseUrl}${TabPaths[Tab.EVENTS]}`,
query: location.query,
}}
size="xs"
analyticsEventKey="issue_details.all_events_clicked"
analyticsEventName="Issue Details: All Events Clicked"
>
{t('All %s', issueTypeConfig.customCopy.eventUnits)}
</LinkButton>
)}
{issueTypeConfig.pages.openPeriods.enabled && (
<LinkButton
to={{
pathname: `${baseUrl}${TabPaths[Tab.OPEN_PERIODS]}`,
query: location.query,
}}
size="xs"
analyticsEventKey="issue_details.all_open_periods_clicked"
analyticsEventName="Issue Details: All Open Periods Clicked"
>
{t('All Open Periods')}
</LinkButton>
)}
{issueTypeConfig.pages.checkIns.enabled && (
<LinkButton
to={{
pathname: `${baseUrl}${TabPaths[Tab.CHECK_INS]}`,
query: location.query,
}}
size="xs"
analyticsEventKey="issue_details.all_checks_ins_clicked"
analyticsEventName="Issue Details: All Checks-Ins Clicked"
>
{t('All Check-Ins')}
</LinkButton>
)}
{issueTypeConfig.pages.uptimeChecks.enabled && (

<IssueDetailsTourElement
id={IssueDetailsTour.ISSUE_DETAILS_NAVIGATION}
title={t('Compare different events')}
description={t(
'You can quickly navigate between different events in this issue to find their similarities (and differences).'
)}
>
<NavigationWrapper>
{currentTab === Tab.DETAILS && (
<Fragment>
<IssueDetailsEventNavigation event={event} group={group} />
{issueTypeConfig.pages.events.enabled && (
<LinkButton
to={{
pathname: `${baseUrl}${TabPaths[Tab.EVENTS]}`,
query: location.query,
}}
size="xs"
analyticsEventKey="issue_details.all_events_clicked"
analyticsEventName="Issue Details: All Events Clicked"
>
{t('All %s', issueTypeConfig.customCopy.eventUnits)}
</LinkButton>
)}
{issueTypeConfig.pages.openPeriods.enabled && (
<LinkButton
to={{
pathname: `${baseUrl}${TabPaths[Tab.OPEN_PERIODS]}`,
query: location.query,
}}
size="xs"
analyticsEventKey="issue_details.all_open_periods_clicked"
analyticsEventName="Issue Details: All Open Periods Clicked"
>
{t('All Open Periods')}
</LinkButton>
)}
{issueTypeConfig.pages.checkIns.enabled && (
<LinkButton
to={{
pathname: `${baseUrl}${TabPaths[Tab.CHECK_INS]}`,
query: location.query,
}}
size="xs"
analyticsEventKey="issue_details.all_checks_ins_clicked"
analyticsEventName="Issue Details: All Checks-Ins Clicked"
>
{t('All Check-Ins')}
</LinkButton>
)}
{issueTypeConfig.pages.uptimeChecks.enabled && (
<LinkButton
to={{
pathname: `${baseUrl}${TabPaths[Tab.UPTIME_CHECKS]}`,
query: location.query,
}}
size="xs"
analyticsEventKey="issue_details.all_uptime_checks_clicked"
analyticsEventName="Issue Details: All Uptime Checks Clicked"
>
{t('All Uptime Checks')}
</LinkButton>
)}
</Fragment>
)}
{isListView && (
<ButtonBar gap={1}>
{issueTypeConfig.discover.enabled && currentTab === Tab.EVENTS && (
<LinkButton
to={discoverUrl}
aria-label={t('Open in Discover')}
size="xs"
icon={<IconTelescope />}
analyticsEventKey="issue_details.discover_clicked"
analyticsEventName="Issue Details: Discover Clicked"
>
{t('Discover')}
</LinkButton>
)}
<LinkButton
to={{
pathname: `${baseUrl}${TabPaths[Tab.UPTIME_CHECKS]}`,
query: location.query,
pathname: `${baseUrl}${TabPaths[Tab.DETAILS]}`,
query: {...location.query, cursor: undefined},
}}
aria-label={t('Return to event details')}
size="xs"
analyticsEventKey="issue_details.all_uptime_checks_clicked"
analyticsEventName="Issue Details: All Uptime Checks Clicked"
>
{t('All Uptime Checks')}
{t('Close')}
</LinkButton>
)}
</Fragment>
)}
{isListView && (
<ButtonBar gap={1}>
{issueTypeConfig.discover.enabled && currentTab === Tab.EVENTS && (
<LinkButton
to={discoverUrl}
aria-label={t('Open in Discover')}
size="xs"
icon={<IconTelescope />}
analyticsEventKey="issue_details.discover_clicked"
analyticsEventName="Issue Details: Discover Clicked"
>
{t('Discover')}
</LinkButton>
)}
<LinkButton
to={{
pathname: `${baseUrl}${TabPaths[Tab.DETAILS]}`,
query: {...location.query, cursor: undefined},
}}
aria-label={t('Return to event details')}
size="xs"
>
{t('Close')}
</LinkButton>
</ButtonBar>
)}
</NavigationWrapper>
</ButtonBar>
)}
</NavigationWrapper>
</IssueDetailsTourElement>
</EventNavigationWrapper>
);
}
Expand Down
Loading

0 comments on commit 99fb3ec

Please sign in to comment.