Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 9 additions & 6 deletions static/app/views/performance/eap/overviewSpansTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {Organization} from 'sentry/types/organization';
import type EventView from 'sentry/utils/discover/eventView';
import type {EventsMetaType} from 'sentry/utils/discover/eventView';
import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
import {decodeScalar} from 'sentry/utils/queryString';
import type {Theme} from 'sentry/utils/theme';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {useLocation} from 'sentry/utils/useLocation';
Expand Down Expand Up @@ -51,13 +52,15 @@ export function OverviewSpansTable({eventView, totalValues, transactionName}: Pr
const projectSlug = projects.find(p => p.id === `${eventView.project}`)?.slug;

const p95 = totalValues?.['p95()'] ?? 0;
const defaultQuery = new MutableSearch('');
defaultQuery.addFilterValue('is_transaction', '1');
defaultQuery.addFilterValue('transaction', transactionName);
const searchQuery = decodeScalar(location.query.query, '');

const countQuery = new MutableSearch('');
countQuery.addFilterValue('is_transaction', '1');
countQuery.addFilterValue('transaction', transactionName);
const defaultQuery = new MutableSearch(searchQuery);
defaultQuery.setFilterValues('is_transaction', ['true']);
defaultQuery.setFilterValues('transaction', [transactionName]);

const countQuery = new MutableSearch(searchQuery);
Comment thread
mjq marked this conversation as resolved.
countQuery.setFilterValues('is_transaction', ['true']);
countQuery.setFilterValues('transaction', [transactionName]);
Comment thread
mjq marked this conversation as resolved.

const {data: numEvents, error: numEventsError} = useSpans(
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {DatePageFilter} from 'sentry/components/pageFilters/date/datePageFilter'
import {EnvironmentPageFilter} from 'sentry/components/pageFilters/environment/environmentPageFilter';
import {PageFilterBar} from 'sentry/components/pageFilters/pageFilterBar';
import {normalizeDateTimeParams} from 'sentry/components/pageFilters/parse';
import {useSpanSearchQueryBuilderProps} from 'sentry/components/performance/spanSearchQueryBuilder';
import {TransactionSearchQueryBuilder} from 'sentry/components/performance/transactionSearchQueryBuilder';
import {t} from 'sentry/locale';
import {DataCategory} from 'sentry/types/core';
Expand All @@ -29,6 +30,7 @@ import {useMaxPickableDays} from 'sentry/utils/useMaxPickableDays';
import {useNavigate} from 'sentry/utils/useNavigate';
import {useRoutes} from 'sentry/utils/useRoutes';
import {hasDatasetSelector} from 'sentry/views/dashboards/utils';
import {TraceItemSearchQueryBuilder} from 'sentry/views/explore/components/traceItemSearchQueryBuilder';
import {useDomainViewFilters} from 'sentry/views/insights/pages/useFilters';
import {OverviewSpansTable} from 'sentry/views/performance/eap/overviewSpansTable';
import {useTransactionSummaryEAP} from 'sentry/views/performance/eap/useTransactionSummaryEAP';
Expand All @@ -48,6 +50,27 @@ import {EventsTable} from './eventsTable';
import type {EventsDisplayFilterName} from './utils';
import {getEventsFilterOptions} from './utils';

function EAPSearchBar({
projects,
initialQuery,
onSearch,
}: {
initialQuery: string;
onSearch: (query: string) => void;
projects: number[];
}) {
const {spanSearchQueryBuilderProps} = useSpanSearchQueryBuilderProps({
projects,
initialQuery,
onSearch,
searchSource: 'transaction_events',
});

return (
<TraceItemSearchQueryBuilder {...spanSearchQueryBuilderProps} disallowFreeText />
);
}

type Props = {
eventView: EventView;
eventsDisplayFilterName: EventsDisplayFilterName;
Expand Down Expand Up @@ -90,8 +113,13 @@ export function EventsContent(props: Props) {
const routes = useRoutes();
const theme = useTheme();
const domainViewFilters = useDomainViewFilters();
const shouldUseEAP = useTransactionSummaryEAP();

const {eventView, titles} = useMemo(() => {
if (shouldUseEAP) {
return {eventView: originalEventView, titles: []};
}

const eventViewClone = originalEventView.clone();
const transactionsListTitles = TRANSACTIONS_LIST_TITLES.slice();
const project = projects.find(p => p.id === projectId);
Expand Down Expand Up @@ -164,6 +192,7 @@ export function EventsContent(props: Props) {
titles: transactionsListTitles,
};
}, [
shouldUseEAP,
originalEventView,
location,
organization,
Expand All @@ -173,8 +202,6 @@ export function EventsContent(props: Props) {
webVital,
]);

const shouldUseEAP = useTransactionSummaryEAP();

const table = shouldUseEAP ? (
<OverviewSpansTable
eventView={eventView}
Expand Down Expand Up @@ -250,7 +277,7 @@ function Search(props: Props) {
const shouldUseEAP = useTransactionSummaryEAP();

const maxPickableDays = useMaxPickableDays({
dataCategories: [DataCategory.TRANSACTIONS],
dataCategories: [shouldUseEAP ? DataCategory.SPANS : DataCategory.TRANSACTIONS],
});
const datePageFilterProps = useDatePageFilterProps(maxPickableDays);

Expand All @@ -270,34 +297,46 @@ function Search(props: Props) {
<DatePageFilter {...datePageFilterProps} />
</PageFilterBar>
<StyledSearchBarWrapper>
<TransactionSearchQueryBuilder
Comment thread
mjq marked this conversation as resolved.
projects={projectIds}
initialQuery={query}
onSearch={handleSearch}
searchSource="transaction_events"
/>
</StyledSearchBarWrapper>
<CompactSelect
trigger={triggerProps => (
<OverlayTrigger.Button {...triggerProps} prefix={t('Percentile')} />
)}
value={eventsDisplayFilterName}
onChange={opt => onChangeEventsDisplayFilter(opt.value)}
options={Object.entries(eventsFilterOptions).map(([name, filter]) => ({
value: name as EventsDisplayFilterName,
label: filter.label,
}))}
/>
<LinkButton
to={eventView.getResultsViewUrlTarget(
organization,
false,
hasDatasetSelector(organization) ? SavedQueryDatasets.TRANSACTIONS : undefined
{shouldUseEAP ? (
<EAPSearchBar
projects={projectIds ?? []}
initialQuery={query}
onSearch={handleSearch}
/>
) : (
<TransactionSearchQueryBuilder
projects={projectIds}
initialQuery={query}
onSearch={handleSearch}
searchSource="transaction_events"
/>
)}
onClick={handleDiscoverButtonClick}
>
{t('Open in Discover')}
</LinkButton>
</StyledSearchBarWrapper>
{!shouldUseEAP && (
<CompactSelect
trigger={triggerProps => (
<OverlayTrigger.Button {...triggerProps} prefix={t('Percentile')} />
)}
value={eventsDisplayFilterName}
onChange={opt => onChangeEventsDisplayFilter(opt.value)}
options={Object.entries(eventsFilterOptions).map(([name, filter]) => ({
value: name as EventsDisplayFilterName,
label: filter.label,
}))}
/>
)}
{!shouldUseEAP && (
<LinkButton
to={eventView.getResultsViewUrlTarget(
organization,
false,
hasDatasetSelector(organization) ? SavedQueryDatasets.TRANSACTIONS : undefined
)}
onClick={handleDiscoverButtonClick}
>
{t('Open in Discover')}
</LinkButton>
)}
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.

Grid template not adjusted for fewer EAP children

Low Severity

The FilterActions grid template defines 5 columns on xl screens (auto auto 1fr auto auto) and 4 on sm (repeat(4, min-content)), designed for the non-EAP case with 5 children. In EAP mode, only 3 children are rendered (the Percentile select and Open in Discover button are hidden). The empty auto columns still produce gap space (space.xl = 16px each), making the search bar ~32px narrower than intended. The analogous EAP layout in transactionOverview/content.tsx correctly uses a 3-column grid (auto auto 1fr).

Fix in Cursor Fix in Web

</FilterActions>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {removeHistogramQueryStrings} from 'sentry/utils/performance/histogram';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {useLocation} from 'sentry/utils/useLocation';
import {useNavigate} from 'sentry/utils/useNavigate';
import {useTransactionSummaryEAP} from 'sentry/views/performance/eap/useTransactionSummaryEAP';
import {
decodeFilterFromLocation,
filterToLocationQuery,
Expand Down Expand Up @@ -38,6 +39,7 @@ function TransactionEvents() {

const navigate = useNavigate();
const location = useLocation();
const shouldUseEAP = useTransactionSummaryEAP();
const eventsDisplayFilterName = decodeEventsDisplayFilterFromLocation(location);
const spanOperationBreakdownFilter = decodeFilterFromLocation(location);
const webVital = getWebVital(location);
Expand Down Expand Up @@ -121,6 +123,26 @@ function TransactionEvents() {
});
};

if (shouldUseEAP) {
return (
<EventsContent
location={location}
organization={organization}
eventView={eventView}
transactionName={transactionName}
spanOperationBreakdownFilter={spanOperationBreakdownFilter}
onChangeSpanOperationBreakdownFilter={onChangeSpanOperationBreakdownFilter}
eventsDisplayFilterName={EventsDisplayFilterName.P100}
onChangeEventsDisplayFilter={onChangeEventsDisplayFilter}
percentileValues={undefined}
projectId={projectId}
projects={projects}
webVital={webVital}
setError={setError}
/>
);
}

return (
<DiscoverQuery
eventView={percentilesView}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
SPAN_OP_RELATIVE_BREAKDOWN_FIELD,
type QueryFieldValue,
} from 'sentry/utils/discover/fields';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {WebVital} from 'sentry/utils/fields';
import {decodeScalar} from 'sentry/utils/queryString';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
Expand Down Expand Up @@ -212,6 +213,7 @@ export function getPercentilesEventView(eventView: EventView): EventView {
export function generateTransactionEventsEventView({
location,
transactionName,
shouldUseEAP,
}: {
location: Location;
organization: Organization;
Expand All @@ -221,7 +223,11 @@ export function generateTransactionEventsEventView({
const query = decodeScalar(location.query.query, '');
const conditions = new MutableSearch(query);

conditions.setFilterValues('event.type', ['transaction']);
if (shouldUseEAP) {
conditions.setFilterValues('is_transaction', ['true']);
} else {
conditions.setFilterValues('event.type', ['transaction']);
}
conditions.setFilterValues('transaction', [transactionName]);

Object.keys(conditions.filters).forEach(field => {
Expand All @@ -230,7 +236,29 @@ export function generateTransactionEventsEventView({
}
});

const orderby = decodeScalar(location.query.sort, '-timestamp');
let orderby = decodeScalar(location.query.sort, '-timestamp');

if (shouldUseEAP) {
orderby = orderby.replace('transaction.duration', 'span.duration');

return EventView.fromNewQueryWithLocation(
{
id: undefined,
version: 2,
name: transactionName,
// TODO(mjq): `fields` is never actually read - the relevant query comes
// from `useSegmentSpansQuery` instead. Confusingly, other fields of
// this EventView _are_ used in various places. Untangling this is a job
// for after the non-EAP branches are removed.
fields: [],
query: conditions.formatString(),
projects: [],
orderby,
dataset: DiscoverDatasets.SPANS,
},
location
);
}

// Default fields for relative span view
const fields = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,27 +100,6 @@ type Props = {

export const SEGMENT_SPANS_CURSOR_NAME = 'segmentSpansCursor';

function EAPSearchQueryBuilder({
projects,
initialQuery,
onSearch,
}: {
initialQuery: string;
onSearch: (query: string) => void;
projects: number[];
}) {
const {spanSearchQueryBuilderProps} = useSpanSearchQueryBuilderProps({
projects,
initialQuery,
onSearch,
searchSource: 'transaction_summary',
});

return (
<TraceItemSearchQueryBuilder {...spanSearchQueryBuilderProps} disallowFreeText />
);
}

function EAPSummaryContentInner({
eventView,
location,
Expand Down Expand Up @@ -258,15 +237,12 @@ function EAPSummaryContentInner({
});
const datePageFilterProps = useDatePageFilterProps(maxPickableDays);

function renderSearchBar() {
return (
<EAPSearchQueryBuilder
projects={projectIds}
initialQuery={query}
onSearch={handleSearch}
/>
);
}
const {spanSearchQueryBuilderProps} = useSpanSearchQueryBuilderProps({
projects: projectIds,
initialQuery: query,
onSearch: handleSearch,
searchSource: 'transaction_summary',
});

return (
<Fragment>
Expand All @@ -277,7 +253,12 @@ function EAPSummaryContentInner({
<EnvironmentPageFilter />
<DatePageFilter {...datePageFilterProps} />
</PageFilterBar>
<StyledSearchBarWrapper>{renderSearchBar()}</StyledSearchBarWrapper>
<StyledSearchBarWrapper>
<TraceItemSearchQueryBuilder
{...spanSearchQueryBuilderProps}
disallowFreeText
/>
</StyledSearchBarWrapper>
</FilterActions>
<EAPChartsWidgetContainer>
<EAPChartsWidget transactionName={transactionName} query={query} />
Expand Down
Loading