Skip to content

Commit

Permalink
ref(performance): Separate header from content in transaction tags (#…
Browse files Browse the repository at this point in the history
…28354)

Continuing from #28343, this separates the header from the content on the
transaction tags tab.
  • Loading branch information
Zylphrex authored and shruthilayaj committed Sep 7, 2021
1 parent 75d8254 commit 07923b5
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 122 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {Fragment, useEffect, useState} from 'react';
import {useEffect, useState} from 'react';
import {browserHistory} from 'react-router';
import styled from '@emotion/styled';
import {Location} from 'history';

import {SectionHeading} from 'app/components/charts/styles';
import SearchBar from 'app/components/events/searchBar';
import * as Layout from 'app/components/layouts/thirds';
import LoadingIndicator from 'app/components/loadingIndicator';
import {getParams} from 'app/components/organizations/globalSelectionHeader/getParams';
import QuestionTooltip from 'app/components/questionTooltip';
Expand All @@ -20,8 +21,6 @@ import {decodeScalar} from 'app/utils/queryString';
import {SidebarSpacer} from 'app/views/performance/transactionSummary/utils';

import {SpanOperationBreakdownFilter} from '../filter';
import TransactionHeader from '../header';
import Tab from '../tabs';
import {getTransactionField} from '../transactionOverview/tagExplorer';

import TagsDisplay from './tagsDisplay';
Expand All @@ -38,9 +37,7 @@ type Props = {
type TagOption = string;

const TagsPageContent = (props: Props) => {
const {eventView, location, organization, projects, transactionName} = props;

const handleIncompatibleQuery = () => {};
const {eventView, location, organization, projects} = props;

const aggregateColumn = getTransactionField(
SpanOperationBreakdownFilter.None,
Expand All @@ -49,18 +46,7 @@ const TagsPageContent = (props: Props) => {
);

return (
<Fragment>
<TransactionHeader
eventView={eventView}
location={location}
organization={organization}
projects={projects}
transactionName={transactionName}
currentTab={Tab.Tags}
hasWebVitals="maybe"
handleIncompatibleQuery={handleIncompatibleQuery}
/>

<Layout.Main fullWidth>
<SegmentExplorerQuery
eventView={eventView}
orgSlug={organization.slug}
Expand All @@ -74,7 +60,7 @@ const TagsPageContent = (props: Props) => {
return <InnerContent {...props} isLoading={isLoading} tableData={tableData} />;
}}
</SegmentExplorerQuery>
</Fragment>
</Layout.Main>
);
};

Expand Down Expand Up @@ -276,15 +262,10 @@ const StyledSectionHeading = styled(SectionHeading)`

// TODO(k-fish): Adjust thirds layout to allow for this instead.
const ReversedLayoutBody = styled('div')`
padding: ${space(2)};
margin: 0;
background-color: ${p => p.theme.background};
flex-grow: 1;
@media (min-width: ${p => p.theme.breakpoints[0]}) {
padding: ${space(3)} ${space(4)};
}
@media (min-width: ${p => p.theme.breakpoints[1]}) {
display: grid;
grid-template-columns: auto 66%;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,144 +1,133 @@
import {Component} from 'react';
import {ReactNode, useState} from 'react';
import {browserHistory} from 'react-router';
import styled from '@emotion/styled';
import {Location} from 'history';

import Feature from 'app/components/acl/feature';
import Alert from 'app/components/alert';
import * as Layout from 'app/components/layouts/thirds';
import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
import GlobalSelectionHeader from 'app/components/organizations/globalSelectionHeader';
import SentryDocumentTitle from 'app/components/sentryDocumentTitle';
import {t} from 'app/locale';
import {PageContent} from 'app/styles/organization';
import {GlobalSelection, Organization, Project} from 'app/types';
import {Organization, Project} from 'app/types';
import {defined} from 'app/utils';
import EventView from 'app/utils/discover/eventView';
import {decodeScalar} from 'app/utils/queryString';
import {MutableSearch} from 'app/utils/tokenizeSearch';
import withGlobalSelection from 'app/utils/withGlobalSelection';
import withOrganization from 'app/utils/withOrganization';
import withProjects from 'app/utils/withProjects';

import {getTransactionName} from '../../utils';
import TransactionHeader from '../header';
import Tab from '../tabs';

import TagsPageContent from './content';

type Props = {
location: Location;
organization: Organization;
projects: Project[];
selection: GlobalSelection;
};

type State = {
eventView: EventView | undefined;
};

class TransactionTags extends Component<Props> {
state: State = {
eventView: generateTagsEventView(
this.props.location,
getTransactionName(this.props.location)
),
};

static getDerivedStateFromProps(nextProps: Readonly<Props>, prevState: State): State {
return {
...prevState,
eventView: generateTagsEventView(
nextProps.location,
getTransactionName(nextProps.location)
),
};
function TransactionTags(props: Props) {
const {location, organization, projects} = props;
const projectId = decodeScalar(location.query.project);
const transactionName = getTransactionName(location);

if (!defined(projectId) || !defined(transactionName)) {
// If there is no transaction name, redirect to the Performance landing page
browserHistory.replace({
pathname: `/organizations/${organization.slug}/performance/`,
query: {
...location.query,
},
});
return null;
}

getDocumentTitle(): string {
const name = getTransactionName(this.props.location);

const hasTransactionName = typeof name === 'string' && String(name).trim().length > 0;

if (hasTransactionName) {
return [String(name).trim(), t('Tags')].join(' \u2014 ');
}

return [t('Summary'), t('Tags')].join(' \u2014 ');
}
const project = projects.find(p => p.id === projectId);

renderNoAccess = () => {
return <Alert type="warning">{t("You don't have access to this feature")}</Alert>;
const [incompatibleAlertNotice, setIncompatibleAlertNotice] = useState<ReactNode>(null);
const handleIncompatibleQuery = (incompatibleAlertNoticeFn, _errors) => {
const notice = incompatibleAlertNoticeFn(() => setIncompatibleAlertNotice(null));
setIncompatibleAlertNotice(notice);
};

render() {
const {organization, projects, location} = this.props;
const {eventView} = this.state;
const transactionName = getTransactionName(location);
if (!eventView || transactionName === undefined) {
// If there is no transaction name, redirect to the Performance landing page
browserHistory.replace({
pathname: `/organizations/${organization.slug}/performance/`,
query: {
...location.query,
},
});
return null;
}

const shouldForceProject = eventView.project.length === 1;
const forceProject = shouldForceProject
? projects.find(p => parseInt(p.id, 10) === eventView.project[0])
: undefined;
const projectSlugs = eventView.project
.map(projectId => projects.find(p => parseInt(p.id, 10) === projectId))
.filter((p: Project | undefined): p is Project => p !== undefined)
.map(p => p.slug);

return (
<SentryDocumentTitle
title={this.getDocumentTitle()}
orgSlug={organization.slug}
projectSlug={forceProject?.slug}
const eventView = generateEventView(location, transactionName);

return (
<SentryDocumentTitle
title={getDocumentTitle(transactionName)}
orgSlug={organization.slug}
projectSlug={project?.slug}
>
<Feature
features={['performance-tag-page']}
organization={organization}
renderDisabled={NoAccess}
>
<Feature
features={['performance-tag-page']}
organization={organization}
renderDisabled={this.renderNoAccess}
<GlobalSelectionHeader
lockedMessageSubject={t('transaction')}
shouldForceProject={defined(project)}
forceProject={project}
specificProjectSlugs={defined(project) ? [project.slug] : []}
disableMultipleProjectSelection
showProjectSettingsLink
>
<GlobalSelectionHeader
lockedMessageSubject={t('transaction')}
shouldForceProject={shouldForceProject}
forceProject={forceProject}
specificProjectSlugs={projectSlugs}
disableMultipleProjectSelection
showProjectSettingsLink
>
<StyledPageContent>
<LightWeightNoProjectMessage organization={organization}>
<StyledPageContent>
<LightWeightNoProjectMessage organization={organization}>
<TransactionHeader
eventView={eventView}
location={location}
organization={organization}
projects={projects}
transactionName={transactionName}
currentTab={Tab.Tags}
hasWebVitals="maybe"
handleIncompatibleQuery={handleIncompatibleQuery}
/>
<Layout.Body>
{incompatibleAlertNotice && (
<Layout.Main fullWidth>{incompatibleAlertNotice}</Layout.Main>
)}
<TagsPageContent
location={location}
eventView={eventView}
transactionName={transactionName}
organization={organization}
projects={projects}
/>
</LightWeightNoProjectMessage>
</StyledPageContent>
</GlobalSelectionHeader>
</Feature>
</SentryDocumentTitle>
);
</Layout.Body>
</LightWeightNoProjectMessage>
</StyledPageContent>
</GlobalSelectionHeader>
</Feature>
</SentryDocumentTitle>
);
}

function getDocumentTitle(transactionName: string): string {
const hasTransactionName =
typeof transactionName === 'string' && String(transactionName).trim().length > 0;

if (hasTransactionName) {
return [String(transactionName).trim(), t('Tags')].join(' \u2014 ');
}

return [t('Summary'), t('Tags')].join(' \u2014 ');
}

function NoAccess() {
return <Alert type="warning">{t("You don't have access to this feature")}</Alert>;
}

const StyledPageContent = styled(PageContent)`
padding: 0;
`;

function generateTagsEventView(
location: Location,
transactionName: string | undefined
): EventView | undefined {
if (transactionName === undefined) {
return undefined;
}
function generateEventView(location: Location, transactionName: string): EventView {
const query = decodeScalar(location.query.query, '');
const conditions = new MutableSearch(query);
const eventView = EventView.fromNewQueryWithLocation(
Expand All @@ -158,4 +147,4 @@ function generateTagsEventView(
return eventView;
}

export default withGlobalSelection(withProjects(withOrganization(TransactionTags)));
export default withProjects(withOrganization(TransactionTags));
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function initializeData({query} = {query: {}}) {
location: {
query: {
transaction: 'Test Transaction',
project: 1,
project: '1',
...query,
},
},
Expand Down Expand Up @@ -141,7 +141,7 @@ describe('Performance > Transaction Tags', function () {

expect(browserHistory.replace).toHaveBeenCalledWith({
query: {
project: 1,
project: '1',
statsPeriod: '14d',
tagKey: 'hardwareConcurrency',
transaction: 'Test Transaction',
Expand Down Expand Up @@ -174,7 +174,7 @@ describe('Performance > Transaction Tags', function () {

expect(browserHistory.replace).toHaveBeenCalledWith({
query: {
project: 1,
project: '1',
statsPeriod: '14d',
tagKey: 'hardwareConcurrency',
transaction: 'Test Transaction',
Expand Down Expand Up @@ -214,7 +214,7 @@ describe('Performance > Transaction Tags', function () {

expect(browserHistory.replace).toHaveBeenCalledWith({
query: {
project: 1,
project: '1',
statsPeriod: '14d',
tagKey: 'effectiveConnectionType',
transaction: 'Test Transaction',
Expand Down

0 comments on commit 07923b5

Please sign in to comment.